Answers:
<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">
。您还可以通过编辑web.xml
和添加“全局”配置
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
另外,您也可以使用<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请求/响应的代码),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
需求,那么,如果不更新组件,则此构造将无法正常工作,原因很简单,因为它是生成的HTML输出的一部分(因此对其中的所有EL表达式进行了求值在渲染响应期间)。value
action
oncomplete
该@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
(这是“无”)。
也可以看看:
process
未设置,所以它使用默认值@form
。以上答案中也对此进行了解释。
如果您很难记住默认值(我知道我有...),这里摘录自BalusC的答案:
组件| 提交| 刷新 ------------ | --------------- | -------------- f:ajax | execute =“ @ this” | render =“ @ none” p:ajax | process =“ @ this” | update =“ @ none” p:commandXXX | process =“ @ form” | update =“ @ none”
process
for 的默认值p:commandXXX
是@all
。另外,这似乎适用于支持AJAX的每个组件,例如p:menuitem
。
@all
?据我从BalusC的答案中可以看出,它是@form
,但是@all
等效@form
于过程。关于其他组件的要点,我想我需要在时间上查看源代码以了解其适用于哪些组件,因为我宁愿不要写可能出错的东西
@all
一点。他必须知道,他最近重新实现了PrimeFaces的AJAX引擎。后来,我仔细检查了一下,但阅读了PrimeFaces的源代码并查看了XHR请求。我希望这次我做对了,因为我已经实现了BootsFaces的AJAX请求,使其与PrimeFaces的AJAX请求完全一样。
请注意,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)"
看到: