温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes

其他 - 了解PrimeFaces流程/更新和JSF f:ajax执行/渲染属性

发布于 2020-03-29 21:55:58

究竟是什么process,并update在PrimeFaces p:commandXxx组件和executerenderf:ajax标签?

验证时哪个有效?update属性是做什么的,而不是从后端更新组件的值?难道process属性绑定值模型?究竟做什么@this@parent@all@form在这两个属性?

下面的示例工作正常,但是我对基本概念有些困惑。

<p:commandButton process="@parent"
                 update="@form"
                 action="#{bean.submit}" 
                 value="Submit" />

查看更多

提问者
Shardendu
被浏览
49
BalusC 2018-09-25 22:24

<p:commandXxx process> <p:ajax process> <f:ajax execute>

process属性是服务器端属性,仅会影响UIComponent实现EditableValueHolder(输入字段)或ActionSource(命令字段)。process属性使用以空格分隔的客户端ID列表告诉JSF,在提交(部分)表单时,必须在整个JSF生命周期中准确处理哪些组件。

然后JSF将应用请求的值(发现基于组件自己的客户端ID的HTTP请求的参数,然后要么在的情况下,将其设置为提交的值EditableValueHolder的部件或排队新ActionEvent中的情况下ActionSource的部件),则执行转换,验证和更新的模型值(EditableValueHolder部件只),最后调用排队ActionEventActionSource仅组件)。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具体processexecute<f:ajax execute>它的行为完全相同,不同之处在于它不支持逗号分隔的字符串,而PrimeFaces则支持(尽管我个人建议仅使用空格分隔的约定),也不支持@parent关键字。另外,了解<p:commandXxx process>默认值为@formwhile <p:ajax process><f:ajax execute>默认值为可能会很有用@this最后,知道process支持所谓的“ PrimeFaces Selectors” 也很有用,另请参见update =“ @(。myClass)”中的PrimeFaces Selectors如何工作?


<p:commandXxx update> <p:ajax update> <f:ajax render>

update属性是客户端,可以影响所有UIComponentHTML表示形式update属性使用空格分隔的客户端ID列表告诉JavaScript(负责处理ajax请求/响应的JavaScript),HTML DOM树中的哪些部分需要更新以响应表单提交。

然后,JSF将为此准备正确的ajax响应,其中包含需要更新的部分。JSF将跳过updateajax响应中属性未涵盖的所有其他组件,从而使响应有效负载保持较小。同样,其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已经存在)

尽管可以正常工作,但在此特定示例中,无需更新输入和命令组件。除非您更改模型值foobar内部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}')" />

想象一下oncompletevalue中更改了with 需求action,那么如果不更新组件,此构造将无法正常工作,原因oncomplete简单,它是生成的HTML输出的一部分(因此,对其中的所有EL表达式进行了评估在渲染响应期间)。

@all更新整个文件,这应小心使用。通常情况下,你想通过代替或者是一个普通的链接(使用这个真正的GET请求<a><h:link>)或重定向消息后发表?faces-redirect=trueExternalContext#redirect()在效果上,process="@form" update="@all"与非ajax(非部分)提交具有完全相同的效果。在我整个JSF生涯中,我遇到的唯一明智的用例@all是完整显示一个错误页面,以防ajax请求期间发生异常。另请参见处理AJAXified组件的JSF 2.0异常的正确方法是什么?

JSF的同等标准的PrimeFaces具体updaterender<f:ajax render>它的行为完全相同,不同之处在于它不支持逗号分隔的字符串,而PrimeFaces则支持(尽管我个人建议仅使用空格分隔的约定),也不支持@parent关键字。双方updaterender默认为@none(这是“无”)。


也可以看看: