Как повторно выполнить функцию javascript после формы reRender?

Мне нужно повторно выполнить javascript сразу после того, как форма будет повторно отображена. Просто, добавление javascript после содержимого XHTML не поможет с момента его частичного запроса. Кроме того, я не могу использовать "onComplete", поскольку commandButton, из которого я переформатирую форму, находится в компоненте JSF, используемом в нескольких местах. Мне нужно установить исправление локально.

Есть ли какой-нибудь способ? Мне было интересно, поможет ли f: ajax в этом случае.

Пожалуйста, дайте мне знать, если кто-нибудь узнает об этом.

Ответ 1

Самый простой способ - просто поместить вызов функции JS в компонент, подлежащий обновлению.

<h:form>
    ...
    <h:commandButton value="submit"><f:ajax render="@form" /></h:commandButton>
    <h:outputScript>someFunction();</h:outputScript>
</h:form>

Таким образом, он выполняется при загрузке страницы, а также, если форма обновляется с помощью ajax.

Что касается самого <f:ajax>, вы также можете использовать его атрибут onevent.

<f:ajax ... onevent="handleAjax" />

с

function handleAjax(data) {
    var status = data.status;

    switch(status) {
        case "begin":
            // This is invoked right before ajax request is sent.
            break;

        case "complete":
            // This is invoked right after ajax response is returned.
            break;

        case "success":
            // This is invoked right after successful processing of ajax response and update of HTML DOM.
            someFunction();
            break;
    }
}

Вы можете добавить глобальный крючок на jsf.ajax.addOnEvent(), чтобы вам не нужно указывать его в каждом отдельном атрибуте onevent <f:ajax>, если функциональное требование применяется к каждому запросу ajax.

jsf.ajax.addOnEvent(handleAjax);

Альтернативой является использование утилиты OmniFaces JSF, которая предлагает <h:onloadScript> для этой цели. Вы можете поместить его в голову так, как хотите.

<h:onloadScript>someFunction();</h:onloadScript>

Это автоматически возвращается на каждый запрос ajax в представлении, поэтому вам не нужно копировать его по нескольким отдельным местам в представлении, которое может быть обновлено ajax или повторить его родительский идентификатор в каждом <f:ajax render>.

Ответ 2

Первый ответ BalusC является наиболее подходящим, если вы хотите выполнить сложные операции с помощью JQuery/JS и не особо обеспокоены this

Для более сложного JS, если вы решите использовать глобальный обработчик событий и, например, используете функции JS для bind для элементов, эти функции будут повторно привязаны (следовательно, выполняются дважды), поэтому вам нужно немного способ определения того, что нужно повторить.

Что я, наконец, сделал, это получить идентификатор от обратного вызова события и выполнить только соответствующий JS/JQuery:

jsf.ajax.addOnEvent(ajaxCompleteProcess);


function ajaxCompleteProcess(data) {
    if (data.status && data.status === 'success') {
        var children1 = data.responseXML.children;
        for (i = 0; i < children1.length; i += 1) {
            var children2 = children1[i].children;
            for (j = 0; j < children2.length; j += 1) {
                var children3 = children2[j].children;
                for (y = 0; y < children3.length; y += 1) {
                    if (children3[y].id.indexOf('javax.faces.ViewState') != -1)
                        continue;
                    elementProcess(('#' + children3[y].id.replace(/\:/g, '\\:')));
                }
            }
        }
    }
}

Примечание: эти уродливые петли for, вероятно, не требуются (вы можете использовать clildren [0]), но я еще не нашел времени, чтобы проверить спецификацию.

Ответ 3

Вы можете добавить jQuery в свое приложение и сделать что-то вроде:

$(#yourComponentId).load(function(){
   //execute javascript.
});

Вы можете посмотреть здесь http://api.jquery.com/load/

LE: на

$(document).ready(function(){
}

OFC.