Понимание процессов / обновлений 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" />

5 ответов

Решение

<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'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 атрибут в компонентах PrimeFaces Ajax, как в <p:commandXxx ... partialSubmit="true"> или же <p:ajax ... partialSubmit="true">, Кроме того, вы также можете использовать <o:form> OmniFaces 3.0+, который по умолчанию это поведение.

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


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

update атрибут на стороне клиента и может влиять на представление HTML всех UIComponent s. 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 а также 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. Эти компоненты сообщения имеют в сгенерированном 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 (что означает "ничего").


Смотрите также:

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

Компонент | Отправить | обновление
------------ | --------------- | --------------
f:ajax       | execute="@this" | не делают = "@ никто"
p:ajax       | process="@this" | не обновление = "@ никто"
p:commandXXX | процесс = "@ форма" | не обновление = "@ никто"

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

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

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

@this: запрашивающий компонент с атрибутом execute обрабатывается / отображается.

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

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

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

Обратите внимание, что PrimeFaces поддерживает стандартные ключевые слова JSF 2.0+:

  • @this Текущий компонент.
  • @all Полный вид.
  • @form Форма ближайшего предка текущего компонента.
  • @none Без компонента.

и стандартные ключевые слова JSF 2.3+:

  • @child(n) n-й ребенок.
  • @composite Ближайший предок составного компонента.
  • @id(id) Используется для поиска компонентов по их идентификатору без учета древовидной структуры компонентов и именования контейнеров.
  • @namingcontainer Контейнер именования ближайшего предка текущего компонента.
  • @parent Родитель текущего компонента.
  • @previous Предыдущий брат.
  • @next Следующий брат.
  • @root Экземпляр представления UIViewRoot может использоваться для начала поиска из корня вместо текущего компонента.

Но он также содержит некоторые ключевые слова PrimeFaces:

  • @row(n) n-я строка.
  • @widgetVar(name) Компонент с заданной widgetVar.

И вы даже можете использовать что-то под названием "PrimeFaces Selectors", которое позволяет вам использовать jQuery Selector API. Например, чтобы обработать все входные данные в элементе с помощью класса CSSmyClass:

process="@(.myClass :input)"

Видеть:

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

При использовании свойств резервного компонента на языке выражений

  • атрибут процесса вызывает методы SETTER
  • атрибут обновления вызывает методы GETTER

первоклассный форум

Другие вопросы по тегам