究竟是什么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" />
<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
该process
属性是服务器端的属性,仅会影响UIComponent
实现EditableValueHolder
(输入字段)或ActionSource
(命令字段)。该process
属性使用以空格分隔的客户端ID列表告诉JSF,在提交(部分)表单时,必须在整个JSF生命周期中准确处理哪些组件。
然后JSF将应用请求的值(发现基于组件自己的客户端ID的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>
如果表单包含要在处理中跳过的更多输入组件,则有时是不希望的,这种情况通常要比基于当前输入组件更新另一个输入组件或某个UI部分的情况要多。一个ajax监听器方法。也就是说,您不希望其他输入组件上的验证错误阻止ajax侦听器方法的执行。
然后是@all
。这对process
属性没有特殊影响,而仅对update
属性有影响。的process="@all"
行为与完全相同process="@form"
。HTML不支持一次提交多个表单。
这里顺便也一个是@none
它可能很有用的情况下,你绝对不需要任何过程,但只希望更新通过某些特定部位update
,特别是那些部分,其内容不依赖于提交的值或动作监听器。
应该注意的是,该process
属性对HTTP请求有效负载(请求参数的数量)没有影响。意思是,发送的HTML表示中包含的“所有内容”的默认HTML行为<h:form>
不会受到影响。如果您的表单很大,并且希望将HTTP请求有效负载减少到仅在处理中绝对必要的那些,即仅将这些process
属性覆盖,则可以partialSubmit
在<p:commandXxx ... partialSubmit="true">
或中的PrimeFaces Ajax组件中设置该属性<p:ajax ... partialSubmit="true">
。或者,您也可以使用<o:form>
默认为这种行为的OmniFaces 3.0+。
JSF的同等标准的PrimeFaces具体process
是execute
从<f:ajax execute>
。它的行为完全相同,不同之处在于它不支持逗号分隔的字符串,而PrimeFaces则支持(尽管我个人建议仅使用空格分隔的约定),也不支持@parent
关键字。另外,了解<p:commandXxx process>
默认值为@form
while <p:ajax process>
和<f:ajax execute>
默认值为可能会很有用@this
。最后,知道process
支持所谓的“ PrimeFaces Selectors” 也很有用,另请参见update =“ @(。myClass)”中的PrimeFaces Selectors如何工作?
<p:commandXxx update>
<p:ajax update>
<f:ajax render>
该update
属性是客户端,可以影响所有UIComponent
的HTML表示形式。该update
属性使用空格分隔的客户端ID列表告诉JavaScript(负责处理ajax请求/响应的JavaScript),HTML DOM树中的哪些部分需要更新以响应表单提交。
然后,JSF将为此准备正确的ajax响应,其中仅包含需要更新的部分。JSF将跳过update
ajax响应中属性未涵盖的所有其他组件,从而使响应有效负载保持较小。同样,其rendered
属性false
在渲染响应阶段评估为的组件也将被跳过。请注意,即使它返回了true
,JavaScript最初也无法在HTML DOM树中对其进行更新false
。您需要包装它或更新其父项。另请参见Ajax update / render在具有rendered属性的组件上不起作用。
通常,您只想更新(部分)表单提交后真正需要在客户端“刷新” 的组件。下面的示例通过来更新整个父表单@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保留在消息组件上,否则@(...)
将无法正常工作!再次,请参见update =“ @(。myClass)”中的PrimeFaces Selectors如何工作以了解详细信息)
在@parent
仅更新父组件,因此其覆盖电流分量和所有的兄弟姐妹和他们的孩子。如果您将表格分为理智的组别并各自负责,则此功能将更为有用。该@this
更新,显然,只有电流分量。通常,仅在需要在action方法中更改组件自己的HTML属性之一时才需要这样做。例如
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
想象一下oncomplete
在value
中更改了with 的需求action
,那么如果不更新组件,此构造将无法正常工作,原因oncomplete
很简单,它是生成的HTML输出的一部分(因此,对其中的所有EL表达式进行了评估在渲染响应期间)。
该@all
更新整个文件,这应小心使用。通常情况下,你想通过代替或者是一个普通的链接(使用这个真正的GET请求<a>
或<h:link>
)或重定向消息后发表?faces-redirect=true
或ExternalContext#redirect()
。在效果上,process="@form" update="@all"
与非ajax(非部分)提交具有完全相同的效果。在我整个JSF生涯中,我遇到的唯一明智的用例@all
是完整显示一个错误页面,以防ajax请求期间发生异常。另请参见处理AJAXified组件的JSF 2.0异常的正确方法是什么?
JSF的同等标准的PrimeFaces具体update
是render
从<f:ajax render>
。它的行为完全相同,不同之处在于它不支持逗号分隔的字符串,而PrimeFaces则支持(尽管我个人建议仅使用空格分隔的约定),也不支持@parent
关键字。双方update
并render
默认为@none
(这是“无”)。
也可以看看:
当我使用update =“”时,备用Bean的托管属性未设置,并且我的@PostConstruct例程失败。有什么想法吗?编辑:•如果您依靠#{param}的托管属性出现在后续的POST请求中,则需要在UICommand组件中将其作为<f:param>包括在内。
可能是panelGroup的过程/更新将处理/更新该panelGroup的内容,例如:<h:panelGroup id =“ pgId”> //此处输入文本<h:panelGroup> <p:commandLink process =“ pgId”更新=“ pgId” />
Thx @BalusC提供了非常好的解释!
@Rapster:因为
process
未设置,所以它使用默认值@form
。以上答案中也对此进行了说明。@Roland:它在应用程序配置中隐藏了另一个更严重的问题。