PrimeFaces process
组件中的update
和p:commandXxx
到execute
标记中的render
和f:ajax
究竟是什么?
验证时哪个有效? update
属性做什么而不是从后端更新组件的值? process
属性绑定值是否为模型?这两个属性中究竟有@this
,@parent
,@all
和@form
到底是什么?
以下示例工作正常,但我对基本概念感到困惑。
<p:commandButton process="@parent"
update="@form"
action="#{bean.submit}"
value="Submit" />
答案 0 :(得分:272)
<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
process
属性是服务器端,只能影响UIComponent
实现EditableValueHolder
(输入字段)或ActionSource
(命令字段)。 process
属性告诉JSF,使用以空格分隔的客户端ID列表,在(部分)表单提交时,必须通过整个JSF生命周期处理哪些组件。
然后,JSF将应用请求值(根据组件自己的客户端ID查找HTTP请求参数,然后在EditableValueHolder
组件的情况下将其设置为提交值或排队新{{3}在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>
或者,如果它们恰好是父ActionEvent
组件的唯一组件,那么您也可以使用@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请求有效负载(请求参数的数量)有 no 影响。意思是,发送&#34;所有内容的默认HTML行为&#34;包含在<h:form>
的HTML表示中的内容不会受到影响。如果您有一个大型表单,并希望将HTTP请求有效负载减少到只有处理中绝对必要的那些,即只有process
属性涵盖的那些,那么您可以在PrimeFaces Ajax中设置partialSubmit
属性<p:commandXxx ... partialSubmit="true">
或<p:ajax ... partialSubmit="true">
中的组件。或者,您也可以使用默认为此行为的UIForm
OmniFaces 3.0+。
与process
相当于PrimeFaces特定execute
的标准JSF是<f:ajax execute>
。它的行为完全相同,只是它不支持逗号分隔的字符串,而PrimeFaces字符串(虽然我个人建议只是坚持空格分隔的约定),而不是@parent
关键字。此外,知道<p:commandXxx process>
默认为@form
而<p:ajax process>
和<f:ajax execute>
默认为@this
可能会有用。最后,了解process
支持所谓的&#34; PrimeFaces选择器&#34;也很有用,另请参阅<o:form>
<p:commandXxx update>
<p:ajax update>
<f:ajax render>
update
属性是客户端,可以影响所有UIComponent
的HTML表示。 update
属性告诉JavaScript(负责处理ajax请求/响应的人),使用空格分隔的客户端ID列表,HTML DOM树中的哪些部分需要更新为对表单提交的响应。
然后,JSF将为此准备正确的ajax响应,仅包含 要更新的请求部分。 JSF将跳过ajax响应中update
属性未涵盖的所有其他组件,从而保持响应有效负载较小。此外,将跳过在呈现响应阶段期间rendered
属性求值为false
的组件。请注意,即使它返回true
,如果最初是false
,JavaScript也无法在HTML DOM树中更新它。您需要将其换行或更新其父级。另请参阅How do PrimeFaces Selectors as in update="@(.myClass)" work?。
通常,您只想更新 在客户端(部分)表单提交。以下示例通过@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,否则@(...)
无法正常工作!再次,请参阅Ajax update/render does not work on a component which has rendered attribute了解详细信息)
@parent
仅更新父组件,从而覆盖当前组件及所有兄弟姐妹及其子组件。如果您将表单中的表单与每个自己的职责分开,这将更有用。 @this
显然只更新当前组件。通常,仅当您需要在操作方法中更改组件的某个HTML属性时,才需要这样做。 E.g。
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
想象一下,oncomplete
需要使用value
中更改的action
,如果组件未更新,则此构造不起作用,原因很简单oncomplete
是生成的HTML输出的一部分(因此在渲染响应期间评估其中的所有EL表达式)。
@all
更新整个文档,应谨慎使用。通常情况下,您希望通过普通链接(<a>
或<h:link>
)或?faces-redirect=true
或{之后的重定向 - POST来使用真正的GET请求。 {1}}。在效果中,ExternalContext#redirect()
与非ajax(非部分)提交具有完全相同的效果。在我的整个JSF职业生涯中,我遇到的process="@form" update="@all"
唯一明智的用例是在ajax请求期间发生异常时完整显示错误页面。另请参阅How do PrimeFaces Selectors as in update="@(.myClass)" work?
与@all
相当于PrimeFaces特定update
的标准JSF是render
。它的行为完全相同,只是它不支持逗号分隔的字符串,而PrimeFaces字符串(虽然我个人建议只是坚持空格分隔的约定),而不是<f:ajax render>
关键字。 @parent
和update
都默认为render
(即#34;没有&#34;)。
另见:
答案 1 :(得分:49)
如果您很难记住默认值(我知道我有......),这里是BalusC答案的简短摘录:
Component | Submit | Refresh ------------ | --------------- | -------------- f:ajax | execute="@this" | render="@none" p:ajax | process="@this" | update="@none" p:commandXXX | process="@form" | update="@none"
答案 2 :(得分:23)
通过进程(在JSF规范中它被称为execute),您告诉JSF将处理限制为指定的组件,其他任何东西都被忽略。
update指示当服务器回复您的请求时将更新哪个元素。
@all :处理/呈现每个组件。
@this :处理/呈现具有execute属性的请求组件。
@form :处理/呈现包含请求组件的表单。
@parent :处理/呈现包含请求组件的父级。
使用Primefaces,您甚至可以使用JQuery选择器,请查看此博客:http://blog.primefaces.org/?p=1867
答案 3 :(得分:1)
请注意,PrimeFaces支持标准的JSF 2.0+关键字:
@this
当前组件。@all
整个视图。@form
当前组件的最接近祖先形式。@none
没有组成部分。和标准的JSF 2.3+关键字:
@child(n)
第n个孩子。@composite
最近的复合组件祖先。@id(id)
用于通过忽略组件树结构和命名容器的ID来搜索组件。@namingcontainer
当前组件的最近祖先命名容器。@parent
当前组件的父级。@previous
先前的兄弟姐妹。@next
下一个兄弟姐妹。@root
视图的UIViewRoot实例,可用于从根目录而不是当前组件开始搜索。但是,它也带有一些PrimeFaces特定关键字:
@row(n)
第n行。@widgetVar(name)
具有指定的widgetVar的组件。您甚至可以使用名为“ PrimeFaces Selectors”的东西,它使您可以使用jQuery Selector API。例如,使用CSS类myClass
处理元素中的所有输入:
process="@(.myClass :input)"
请参阅: