understanding process and update

来源:互联网 发布:mysql数据库的优化 编辑:程序博客网 时间:2024/05/18 02:27

http://stackoverflow.com/questions/25339056/understanding-process-and-update-attributes-of-primefaces

process

The process attribute is server side and can only affect UIComponents implementing EditableValueHolder (input fields) or ActionSource (command fields). The process attribute tells JSF by a spaceseparated collection of client IDs which components exactly must be processed through the entire JSF lifecycle upon (partial) form submit. This covers applying the request values (finding HTTP request parameter based on component's own client ID and then either setting it as submitted value in case ofEditableValueHolder components or queueing a new ActionEvent in case of ActionSource components), performing conversion, validation and updating the model values (EditableValueHolder components only) and finally invoking the queuedActionEvent (ActionSource components only). JSF will skip processing of all other components which are not covered byprocess attribute.

Note that it's in case of ActionSource components (such as <p:commandButton>) very important that you also include the component itself in theprocess attribute, particularly if you intend to invoke the action associated with the component. So the below example which intends to process only certain input component(s) when a certain command component is invoked ain't gonna work:

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

It would only process the #{bean.foo} and not the#{bean.action}. You'd need to include the command component itself as well:

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

Or, as you apparently found out, using @parent if they happen to be the only components having a common 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>

Or, if they both happen to be the only components of the parent UIForm component, then you can also use @form:

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

This is sometimes undesirable if the form contains more input components which you'd like to skip in processing, more than often in cases when you'd like to update another input component(s) or some UI section based on the current input component in an ajax listener method. You namely don't want that validation errors on other input components are preventing the ajax listener method from being executed.

Then there's the @all. This has no special effect in process attribute, but only inupdate attribute. A process="@all" behaves exactly the same asprocess="@form". HTML doesn't support submitting multiple forms at once anyway.

There's by the way also a @none which may be useful in case you absolutely don't need to process anything, butonly want to update some specific parts via update, particularly those sections whose content doesn't depend on submitted values or action listeners.

The standard JSF equivalent to the PrimeFaces specific process isexecute from <f:ajax execute>. It behaves exactly the same expect that it doesn't support a commaseparated string while the PrimeFaces one does (although I personally recommend to just stick to spaceseparated convention). Also, it may be useful to know that <p:commandXxx process> defaults to @form while <p:ajax process> and <f:ajax execute> defaults to@this. Finally, it's also useful to know that process supports the so-called "PrimeFaces Selectors", see alsoHow do PrimeFaces Selectors as in update="@(.myClass)" work?


update

The update attribute is client side and can affect the HTML representation of allUIComponents. The update attribute tells JavaScript (the one responsible for handling the ajax request/response) by a spaceseparated collection of client IDs which parts in the HTML DOM tree need to be updated as response to the form submit. JSF will then prepare the right ajax response for that, containing only the requested parts to update. JSF will skip all other components which are not covered byupdate attribute in the ajax response, hereby keeping the response payload small.

Usually, you'd like to update only the components which really need to be "refreshed" in the client side upon (partial) form submit. The example below updates the entire parent form via@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>

(note that process attribute is omitted as that defaults to @form already)

Whilst that may work fine, the update of input and command components is in this particular example unnecessary. Unless you change the model valuesfoo and bar inside action method (which would in turn be unintuitive in UX perspective), there's no point of updating them. The message components are the only whichreally need to be updated:

<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>

However, that gets tedious when you have many of them. That's one of the reasons why PrimeFaces Selectors exist. Those message components have in the generated HTML output a common style class ofui-message, so the following should also do:

<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>

(note that you should keep the IDs on message components, otherwise @(...) won't work! Again, see How do PrimeFaces Selectors as in update="@(.myClass)" work? for detail)

The @parent updates only the parent component, which thus covers the current component and all siblings and their children. This is more useful if you have separated the form in sane groups with each its own responsibility. The@this updates, obviously, only the current component. Normally, this is only necessary when you need to change one of the component's own HTML attributes in the action method. E.g.

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

Imagine that the oncomplete needs to work with the value which is changed inaction, then this construct wouldn't have worked if the component isn't updated, for the simple reason thatoncomplete is part of generated HTML output (and thus all EL expressions in there are evaluated during render response).

The @all updates the entire document, which should be used with care. Normally, you'd like to use a true GET request for this instead by either a plain link (<a> or<h:link>) or a redirect-after-POST by ?faces-redirect=true orExternalContext#redirect(). In effects, process="@form" update="@all" has exactly the same effect as a non-ajax (non-partial) submit. In my entire JSF career, the only sensible use case I encountered for@all is to display an error page in its entirety in case an exception occurs during an ajax request. See alsoWhat is the correct way to deal with JSF 2.0 exceptions for AJAXified components?

The standard JSF equivalent to the PrimeFaces specific update is render from <f:ajax render>. It behaves exactly the same expect that it doesn't support a commaseparated string while the PrimeFaces one does (although I personally recommend to just stick to spaceseparated convention). Bothupdate and render defaults to @none (which is, "nothing").

0 0
原创粉丝点击