Как я могу вызвать функцию JavaScript после каждого ответа AJAX a4j? - PullRequest
3 голосов
/ 27 октября 2011

Я работаю над веб-приложением, используя JSF с Seam.Я хочу иметь возможность вызывать функцию JavaScript после каждого ответа ajax.Я ищу способ сделать это, не помещая атрибут oncomplete в каждый commandLink / commandButton на каждой странице.

Я думаю, что есть способ настроить фильтр сервлета (перехватчик? Я запутался в терминах)ввести вызов JS в каждый ответ.Я собираюсь разобраться в этом.В то же время, если у кого-то есть другие предложения, я весь слух.

РЕДАКТИРОВАТЬ: Я думаю, что jQuery ajaxSuccess метод может быть путь, но я не уверен, как на самом деле его использовать,Я ничего не могу зарегистрировать.Я в основном хочу добавить код, чтобы получать любые и все ajax-запросы из любого источника для вызова моего метода JavaScript в случае успеха.Кто-нибудь может показать мне правильный способ сделать это?Я пытался сделать это несколькими способами, включая добавление jQuery("*").ajaxSuccess(function(){myFunction();}); внизу моего файла шаблона xhtml.

Ответы [ 4 ]

4 голосов
/ 03 ноября 2011

Переписанный ответ: см. Оригинальный ответ в истории изменений

Вы можете переопределить метод send по умолчанию XMLHttpRequest с помощью метода, который перехватывает обработчик readystatechange:

(function () 
{ 
    var xhrSend = XMLHttpRequest.prototype.send; 
    XMLHttpRequest.prototype.send = function  () 
     { 
        var handler = this.onreadystatechange; 
        this.onreadystatechange = function () 
        { 
            if (handler) {
                if (handler.handleEvent) handler.handleEvent.apply(xhr, arguments);
                else handler.apply(xhr, arguments);
            }
            if (this.readyState == 4) 
            { 
                // your oncomplete function here 
                this.onreadystatechange = handler; 
             } 
         }; 
        xhrSend.apply(this, arguments); 
    }; 
})(); 

Редактировать: Вышеприведенная функция не работает с запросами jQuery, и, следовательно, потенциально может не работать с другими библиотеками. Редакция ниже решает проблему с хаком setTimeout для задержки кода, который переопределяет обработчик. Конечно, в jQuery вы можете просто использовать глобальный обработчик .ajaxSuccess(), но для других библиотек с аналогичным поведением это было бы полезно.

(function() {
    function globalHandler() {
        if (this.readyState == 4) {
            // your oncomplete code here
        }
    }
    var xhrSend = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.send = function() {
        var xhr = this;
        if (xhr.addEventListener) {
            xhr.removeEventListener("readystatechange", globalHandler);
            xhr.addEventListener("readystatechange", globalHandler, false);
        }
        else {
            function readyStateChange() {
                if (handler) {
                    if (handler.handleEvent)
                        handler.handleEvent.apply(xhr, arguments);
                    else
                        handler.apply(xhr, arguments);
                }
                globalHandler.apply(xhr, arguments);
                setReadyStateChange();
            }
            function setReadyStateChange() {
                setTimeout(function() {
                    if (xhr.onreadystatechange != readyStateChange) {
                        handler = xhr.onreadystatechange;
                        xhr.onreadystatechange = readyStateChange;
                    }
                }, 1);
            }
            var handler;
            setReadyStateChange();
        }
        xhrSend.apply(xhr, arguments);
    };
})();

http://jsfiddle.net/gilly3/FuacA/5/
Я проверял это в IE7-9 и последних версиях Chrome и FF

3 голосов
/ 27 октября 2011

Поскольку вы используете RichFaces, вы можете просто использовать это:

<a:status id="globalStatus" onstart="onRequestStart()" onstop="onRequestEnd()" />
2 голосов
/ 05 ноября 2011

Использование a4j: status должно работать, но оно должно быть внутри тега h: form:

<h:form id="randomForm" styleClass="edit">
        <a:status id="stateStatus"
         onstart="Richfaces.showModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=true;"
         onstop="Richfaces.hideModalPanel('waitBx'),document.getElementById('randomForm:search').disabled=false;"
        styleClass="message" >
</a:status>

...... way more code  
</form> 

После каждого вызова ajax это вызывает изображение ожидания и отключает кнопку поиска.

Интересно, что, по крайней мере, в нашем коде это не работает ни для чего во вложенном a4j: region.

1 голос
/ 27 октября 2011
...