哪个在验证时工作? update属性做什么,而不是从后端更新值到组件?进程属性绑定值到模型?这两个属性中的@this,@parent,@all和@form究竟是什么?
下面的例子是工作正常,但我有点困惑的基本概念。
<p:commandButton process="@parent" update="@form" action="#{bean.submit}" value="Submit" />
进程属性是服务器端,只能影响实现EditableValueHolder
(输入字段)或ActionSource
(命令字段)的UIComponent
。 process属性告诉JSF,使用空格分隔的客户机ID列表,在(部分)表单提交时,哪些组件必须在整个JSF生命周期中处理。
JSF然后将应用请求值(基于组件自己的客户端ID查找HTTP请求参数,然后在EditableValueHolder组件的情况下将其设置为提交值,或者在ActionSource组件的情况下排队新的ActionEvent
),执行转换,验证和更新模型值(仅限EditableValueHolder组件),最后调用排队的ActionEvent(仅限ActionSource组件)。 JSF将跳过对未被进程属性覆盖的所有其他组件的处理。此外,在应用请求值阶段期间其呈现属性评估为假的组件也将被跳过作为防止被篡改请求的安全措施的一部分。
请注意,在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。这在进程属性中没有特殊效果,但只在update属性中。 process =“@ all”的行为与process =“@ form”完全相同。 HTML不支持一次提交多个表单。
还有一个@none,这可能是有用的,如果你绝对不需要处理任何东西,但只想通过更新更新一些特定的部分,特别是那些内容不依赖于提交的值或动作侦听器。
相当于PrimeFaces特定进程的标准JSF是从< f:ajax execute>执行的。它的行为完全相同,除了它不支持逗号分隔的字符串,而PrimeFaces(尽管我个人建议只是坚持使用空格分隔的约定),也不支持@parent关键字。此外,可能有用的是知道< p:commandXxx process>默认为@form while< p:ajax process>和< f:ajax execute>默认为@this。最后,知道该过程支持所谓的“PrimeFaces选择器”也是有用的,另见How do PrimeFaces Selectors as in update=”@(.myClass)” work?
< p:commandXxx update> < p:ajax update> < f:ajax render>
update属性是客户端,可以影响所有UIComponent的HTML表示。 update属性告诉JavaScript(负责处理ajax请求/响应的),使用客户端ID的空格分隔列表,需要更新HTML DOM树中的哪些部分作为对表单提交的响应。
然后JSF将为其准备正确的ajax响应,仅包含要更新的请求部分。 JSF将跳过ajax响应中未被update属性覆盖的所有其他组件,从而保持响应有效载荷较小。此外,在呈现响应阶段期间其呈现属性评估为false的组件将被跳过。请注意,即使它将返回true,JavaScript不能在HTML DOM树中更新它,如果它最初为false。你需要换行或更新它的父代。参见Ajax update/render does not work on a component which has rendered attribute。
通常,您只想更新(部分)表单提交时真正需要在客户端“刷新”的组件。下面的示例通过@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>
(注意,你应该保留ID在消息组件,否则@(…)将无法工作!再次,详细请参见How do PrimeFaces Selectors as in update=”@(.myClass)” work?)
@parent仅更新父组件,从而覆盖当前组件和所有同级组件及其子组件。这是更有用的,如果你已经分离窗体中的单词组与每个自己的责任。 @this更新,显然,只有当前组件。通常,只有在需要更改action方法中组件自身的HTML属性时,才需要这样做。例如。
<p:commandButton action="#{bean.action}" update="@this" oncomplete="doSomething('#{bean.value}')" />
想象一下,oncomplete需要使用在操作中更改的值,然后如果组件没有更新,这个构造将不会工作,因为oncomplete是生成的HTML输出的一部分(因此所有EL表达式在渲染响应期间评估)。
@all更新整个文档,应小心使用。通常,您想要使用一个真正的GET请求,而不是通过一个普通的链接(< a>或< h:link>)或一个重定向后POST由… faces-redirect = true或ExternalContext# redirect()。在效果中,process =“@ form”update =“@ all”具有与非ajax(非部分)提交完全相同的效果。在我的整个JSF生涯中,我遇到的唯一明智的用例@all是显示一个错误页面,以便在ajax请求期间发生异常。参见What is the correct way to deal with JSF 2.0 exceptions for AJAXified components?
相当于PrimeFaces特定更新的标准JSF从< f:ajax render>呈现。它的行为完全相同,除了它不支持一个逗号分隔的字符串,而PrimeFaces(虽然我个人建议只是坚持使用空格分隔的约定),也不支持@parent关键字。更新和渲染默认为@none(这是“无”)。
也可以看看:
> How to find out client ID of component for ajax update/render? Cannot find component with expression “foo” referenced from “bar”
> Execution order of events when pressing PrimeFaces p:commandButton
> How to decrease request payload of p:ajax during e.g. p:dataTable pagination
> How to show details of current row from p:dataTable in a p:dialog
> How to use <h:form> in JSF page? Single form? Multiple forms? Nested forms?