<p:commandXxx process> <p:ajax process> <f:ajax execute>
processАтрибут на стороне сервера и может повлиять только UIComponentS , реализующие 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's 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атрибуте. А process="@all"ведет себя точно так же, как process="@form". HTML не поддерживает отправку нескольких форм одновременно.
Между прочим, есть еще один, @noneкоторый может быть полезен в случае, если вам абсолютно не нужно ничего обрабатывать, а нужно только обновить некоторые конкретные части update, особенно те разделы, содержимое которых не зависит от представленных значений или слушателей действий.
Следует отметить, что processатрибут не влияет на полезную нагрузку HTTP-запроса (количество параметров запроса). Это означает, что поведение HTML по умолчанию при отправке «всего», содержащегося в представлении HTML, <h:form>не будет затронуто. Если у вас большая форма и вы хотите уменьшить полезную нагрузку HTTP-запроса только до этих абсолютно необходимых при обработке, то есть только тех, которые покрыты processатрибутом, то вы можете установить partialSubmitатрибут в компонентах Ajax PrimeFaces как в <p:commandXxx ... partialSubmit="true">или <p:ajax ... partialSubmit="true">. Вы также можете настроить это «глобально», отредактировав web.xmlи добавив
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
Кроме того, вы также можете использовать <o:form>OmniFaces 3.0+, который по умолчанию это поведение.
Стандартный JSF - эквивалентно PrimeFaces конкретное processсоставляет executeот<f:ajax execute> . Он ведет себя точно так же, за исключением того, что он не поддерживает строку, разделенную запятыми, в отличие от строки PrimeFaces (хотя я лично рекомендую придерживаться соглашения, разделенного пробелами), а также @parentключевое слово. Также может быть полезно знать, что по <p:commandXxx process>умолчанию используется @formwhile, <p:ajax process>а по <f:ajax execute>умолчанию - @this. Наконец, также полезно знать, что processподдерживает так называемые «селекторы PrimeFaces», см. Также Как работают селекторы PrimeFaces, как в update = "@ (. MyClass)"?
<p:commandXxx update> <p:ajax update> <f:ajax render>
updateАтрибут на стороне клиента и может повлиять на HTML представление всех UIComponentс. updateАтрибут сообщает JavaScript (один отвечает за обработку Ajax запрос / ответ), используя разделенный пробелами список идентификаторов клиентов, которые в части необходимости дерева HTML DOM будет обновляться по мере ответа на форме представить.
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 и метод barinside 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. Эти компоненты сообщений имеют в сгенерированном 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" сути имеет тот же эффект, что и не-ajax (не частичная) передача. За всю мою карьеру в JSF единственным разумным вариантом использования, с которым я столкнулся, @allявляется отображение страницы с ошибкой в полном объеме в случае возникновения исключения во время запроса AJAX. См. Также Как правильно обрабатывать исключения JSF 2.0 для компонентов AJAXified?
Стандартный JSF - эквивалентно специфический PrimeFaces updateэто renderот <f:ajax render>. Он ведет себя точно так же, за исключением того, что он не поддерживает строку, разделенную запятыми, в отличие от строки PrimeFaces (хотя я лично рекомендую придерживаться соглашения, разделенного пробелами), а также @parentключевое слово. Как updateи по renderумолчанию@none (то есть «ничего»).
Смотрите также: