Понимание процесса/обновления PrimeFaces и JSF f: атрибуты ajax execute/render

Что такое process и update в компонентах PrimeFaces p:commandXxx и execute и render в теге f:ajax?

Что работает во время проверки? Что делает атрибут update, а не обновляет значение для компонента из задней части? Использовать значение привязки атрибута process для модели? Что именно делают @this, @parent, @all и @form в обоих атрибутах?

Пример ниже работает нормально, но я немного запутался в основных понятиях.

<p:commandButton process="@parent"
                 update="@form"
                 action="#{bean.submit}" 
                 value="Submit" />

Ответ 1

<p:commandXxx process> <p:ajax process> <f:ajax execute>

Атрибут process является стороной сервера и может влиять только на UIComponent, реализуя EditableValueHolder (поля ввода) или ActionSource (поля команд). Атрибут process сообщает JSF, используя список идентификаторов клиентов, разделенных пробелами, которые должны обрабатываться точно по всему жизненному циклу JSF при отправке (частичной) формы.

Затем JSF применяет значения запроса (поиск параметра HTTP-запроса на основе собственного идентификатора клиента компонента, а затем либо установку его в качестве представленного значения в случае компонентов EditableValueHolder, либо очередность нового ActionEvent в случае компонентов ActionSource), выполните преобразование, проверку и обновление значений модели (только EditableValueHolder только компоненты) и, наконец, вызовите компоненты ActionEvent (ActionSource в очереди только). JSF пропустит обработку всех других компонентов, которые не покрываются атрибутом process. Кроме того, компоненты, чей атрибут rendered оценивается как false во время применения фазы запроса запроса, также будут пропущены как часть защиты от подделанных запросов.

Обратите внимание, что это в случае ActionSource компонентов (например, <p:commandButton>) очень важно, что вы также включаете сам компонент в атрибут process, особенно если вы намереваетесь вызвать действие, связанное с компонентом. Таким образом, нижеприведенный пример, который намеревается обрабатывать только определенные входные компоненты (компоненты) при вызове определенного командного компонента, не будет работать:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="foo" action="#{bean.action}" />

Он обрабатывал только #{bean.foo} и не #{bean.action}. Вам также нужно будет включить компонент команды:

<p:inputText id="foo" value="#{bean.foo}" />
<p:commandButton process="@this foo" action="#{bean.action}" />

Или, как вы, по-видимому, обнаружили, используя @parent, если они являются единственными компонентами, имеющими общий родительский элемент:

<p:panel><!-- Type doesn't matter, as long as it a common parent. -->
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@parent" action="#{bean.action}" />
</p:panel>

Или, если они оба являются единственными компонентами родительского компонента UIForm, вы также можете использовать @form:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@form" action="#{bean.action}" />
</h:form>

Это иногда нежелательно, если форма содержит больше входных компонентов, которые вы хотели бы пропустить при обработке, чаще, чем в случаях, когда вы хотите обновить другой компонент ввода или некоторый раздел пользовательского интерфейса на основе текущего входной компонент в методе прослушивания ajax. Вы не хотите, чтобы ошибки проверки на других входных компонентах предотвращали выполнение метода слушателя ajax.

Тогда существует @all. Это не имеет особого эффекта в атрибуте process, но только в атрибуте update. A process="@all" ведет себя точно так же, как process="@form". HTML не поддерживает отправку нескольких форм одновременно.

Там, кстати, также есть @none, который может быть полезен, если вам абсолютно не нужно что-либо обрабатывать, но только хотите обновить некоторые определенные части через update, особенно те разделы, содержимое которых не зависит на отправленные значения или прослушиватели действий.

Стандартная JSF, эквивалентная специфическому для PrimeFaces process, равна execute от <f:ajax execute>. Он ведет себя точно так же, за исключением того, что он не поддерживает строку, разделенную запятыми, в то время как PrimeFaces делает (хотя я лично рекомендую просто придерживаться соглашения, разделенного пробелами), и ключевое слово @parent. Кроме того, может быть полезно знать, что <p:commandXxx process> по умолчанию - @form, а <p:ajax process> и <f:ajax execute> по умолчанию - @this. Наконец, полезно также знать, что process поддерживает так называемые "PrimeFaces Selectors", см. Также Как выбирают PrimeFaces Selectors как в update = "@(. MyClass)" работать?


<p:commandXxx update> <p:ajax update> <f:ajax render>

Атрибут update является клиентской и может влиять на представление HTML всех UIComponent s. Атрибут update указывает JavaScript (тот, который отвечает за обработку запроса/ответа ajax), используя список идентификаторов клиента, разделенных пробелами, которые необходимо обновить в дереве HTML DOM в качестве ответа на форму submit.

Затем JSF подготовит для него правильный ответ ajax, содержащий только запрошенные части для обновления. JSF пропустит все другие компоненты, которые не покрываются атрибутом update в ответе ajax, тем самым сохраняя полезную нагрузку ответа небольшой. Кроме того, компоненты, чей атрибут rendered оценивается как false во время фазы ответа рендеринга, будут пропущены. Обратите внимание, что даже если он вернет true, JavaScript не сможет обновить его в дереве HTML DOM, если он был первоначально false. Вам нужно будет обернуть его или обновить родительский элемент. См. Также Обновление/рендеринг Ajax не работает на компоненте, который предоставил атрибут.

Обычно вы хотите обновить только те компоненты, которые действительно нужно "обновить" на стороне клиента после (частичного) представления формы. Пример ниже обновляет всю родительскую форму с помощью @form:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="@form" />
</h:form>

(обратите внимание, что атрибут process опущен, поскольку он по умолчанию равен @form)

В то время как это может работать нормально, обновление компонентов ввода и команды в этом конкретном примере не требуется. Если вы не измените значения модели foo и bar внутри метода action (что, в свою очередь, будет неинтуитивным в перспективе UX), нет смысла их обновлять. Компоненты сообщения являются единственными, которые действительно нуждаются в обновлении:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="foo_m bar_m" />
</h:form>

Однако это утомительно, когда у вас их много. Это одна из причин, почему существуют PrimeFaces Selectors. Эти компоненты сообщения в генерируемом HTML выводят общий класс стиля ui-message, поэтому также следует выполнить следующее:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" required="true" />
    <p:message id="foo_m" for="foo" />
    <p:inputText id="bar" value="#{bean.bar}" required="true" />
    <p:message id="bar_m" for="bar" />
    <p:commandButton action="#{bean.action}" update="@(.ui-message)" />
</h:form>

(обратите внимание, что вы должны хранить идентификаторы в компонентах сообщений, иначе @(...) не будет работать! Опять же, см. Как выбрать PrimeFaces как в update = " @(. myClass) "работать? для подробностей)

@parent обновляет только родительский компонент, который, таким образом, покрывает текущий компонент и всех братьев и сестер и их детей. Это более полезно, если вы разделили форму в разумных группах с каждой своей ответственностью. @this обновляет, очевидно, только текущий компонент. Обычно это необходимо только тогда, когда вам нужно изменить один из собственных атрибутов HTML компонента в методе действий. Например.

<p:commandButton action="#{bean.action}" update="@this" 
    oncomplete="doSomething('#{bean.value}')" />

Представьте, что oncomplete должен работать с value, который был изменен в action, тогда эта конструкция не сработала бы, если компонент не обновлен по той простой причине, что oncomplete часть сгенерированного вывода HTML (и, следовательно, все EL-выражения в нем оцениваются во время отклика рендера).

@all обновляет весь документ, который следует использовать с осторожностью. Обычно вы хотите использовать настоящий запрос GET для этого вместо простой ссылки (<a> или <h:link>) или перенаправления после POST на ?faces-redirect=true или ExternalContext#redirect(). В эффектах process="@form" update="@all" имеет тот же эффект, что и non-ajax (non-partial) submit. Во всей моей карьере JSF единственным разумным случаем использования, с которым я столкнулся в @all, является полное отображение страницы ошибки в случае возникновения исключения во время запроса ajax. См. Также Каков правильный способ справиться с исключениями JSF 2.0 для компонентов AJAXified?

Стандартная JSF, эквивалентная специфическому update, равна render от <f:ajax render>. Он ведет себя точно так же, за исключением того, что он не поддерживает строку, разделенную запятыми, в то время как PrimeFaces делает (хотя я лично рекомендую просто придерживаться соглашения, разделенного пробелами), и ключевое слово @parent. Как update, так и render по умолчанию используется @none (это "ничего" ).


См. также:

Ответ 2

Если вам трудно запомнить значения по умолчанию (я знаю, что у меня есть...) здесь короткая выдержка из ответа BalusC:

Component    | Submit          | Refresh
------------ | --------------- | --------------
f:ajax       | execute="@this" | render="@none"
p:ajax       | process="@this" | update="@none"
p:commandXXX | process="@form" | update="@none"

Ответ 3

По процессу (в спецификации JSF он называется execute) вы указываете JSF ограничить обработку компонентом, который указан, все остальное просто игнорируется.

update указывает, какой элемент будет обновляться, когда сервер ответит на ваш запрос.

@all: каждый компонент обрабатывается/отображается.

@this: обрабатываемый/обработанный компонент с атрибутом execute.

@form. Форма, содержащая запрашивающий компонент, обрабатывается/отображается.

@parent. Родитель, содержащий запрашивающий компонент, обрабатывается/отображается.

С помощью Primefaces вы можете даже использовать селектор JQuery, посмотрите этот блог: http://blog.primefaces.org/?p=1867