理解PrimeFaces流程/更新和JSF f:Ajax执行/呈现属性

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (17)

究竟什么是processupdate在PrimeFacesp:commandXxx组件和executerenderf: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属性是服务器端,process属性使用客户端ID的空格分隔列表告诉JSF,在(部分)表单提交时,必须在整个JSF生命周期中处理哪些组件。

然后,JSF将应用请求值(根据组件自己的客户机ID查找HTTP请求参数,然后将其设置为提交的值,执行转换、验证和更新模型值(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>

则还可以使用@form:

<h:form>
    <p:inputText id="foo" value="#{bean.foo}" />
    <p:commandButton process="@form" action="#{bean.action}" />
</h:form>

如果表单包含更多的输入组件,在处理过程中要跳过这些组件,这有时是不可取的,在您想要根据Ajax侦听器方法中的当前输入组件更新另一个输入组件或某个UI部分时,这种情况更常见。也就是说,您不希望其他输入组件上的验证错误妨碍Ajax侦听器方法的执行。

然后是@a这在process属性,但仅在update属性。阿process="@all"行为与process="@form". HTML doesn't support submitting multiple forms at once anyway.

顺便说一句还有一个@none如果你完全不需要处理任何事情,这可能是有用的,但是想通过update,尤其是那些其内容不依赖于提交的值或操作侦听器的部分。

等效于PrimeFaces的标准JSFprocessexecute<f:ajax execute>。它的行为完全相同,只是它不支持逗号分隔的字符串,而PrimeFaces则支持(虽然我个人建议只使用空格分隔的约定),也不支持@parent关键词。另外,知道<p:commandXxx process>默认为@form<p:ajax process><f:ajax execute>默认为@thi。最后,知道process支持所谓的“PrimeFaces选择器”

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

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

JSF将为此准备正确的Ajax响应,包括要求更新的部件。JSF将跳过所有未由update属性,从而使响应有效负载保持较小。另外,其组件rendered属性计算为false在呈现响应阶段将被跳过。请注意,即使它会返回true,JavaScript无法在HTMLDOM树中更新它,如果它最初是false。您需要包装它或更新它的父级。

通常,你想要更新各部件真的需要在(部分)表单提交时在客户端“刷新”。下面的示例通过以下方法更新整个父窗体@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)

虽然这可能很好,但是在这个特定的例子中,没有必要更新输入和命令组件。除非您更改模型值foobaraction方法(在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>

@parent只更新父组件,因此涵盖当前组件和所有兄弟姐妹及其子组件。如果你已经把形式分成了理智的团体,并各自负责,这就更有用了。大@this更新,显然,只有当前组件。通常,只有当您需要在action方法中更改组件自己的HTML属性时,这才是必要的。例如:

<p:commandButton action="#{bean.action}" update="@this" 
    oncomplete="doSomething('#{bean.value}')" />

想象一下oncomplete需要使用value中更改的action,那么如果组件没有更新,这个构造就无法工作,原因很简单:oncomplete是生成的HTML输出的一部分(因此,其中的所有EL表达式都是在呈现响应期间计算的)。

@all更新整个文档,应该谨慎使用。通常,希望使用一个真正的GET请求,而不是通过一个普通链接(<a><h:link>)或者是在邮件后重定向。?faces-redirect=trueExternalContext#redirect()...。在效果上,process="@form" update="@all"具有与非Ajax(非部分)提交完全相同的效果。在我整个JSF职业生涯中,我遇到的唯一明智的用例@all是显示整个错误页,以防Ajax请求期间出现异常。

等效于PrimeFaces的标准JSFupdaterender<f:ajax render>...。它的行为完全相同,只是它不支持逗号分隔的字符串,而PrimeFaces则支持(虽然我个人建议只使用空格分隔的约定),也不支持@parent关键词。双双updaterender默认为@none(即“无”)。

用户回答回答于

如果很难记住默认值,下面是BalusC的答案的简短摘录:

Component    | Submit          | Refresh
------------ | --------------- | --------------
f:ajax       | execute="@this" | render="@none"
p:ajax       | process="@this" | update="@none"
p:commandXXX | process="@form" | update="@none"

扫码关注云+社区