在PrimeFaces p:commandXxx组件和在f:ajax标签中执行和呈现的过程和更新究竟是什么?

哪个在验证时有效?更新属性做什么,而不是从后端更新组件的值?流程属性是否将值绑定到模型?@this, @parent, @all和@在这两个属性中到底形成了什么?

下面的例子工作得很好,但我在基本概念上有点困惑。

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

当前回答

通过进程(在JSF规范中称为execute),您告诉JSF将处理限制在指定的组件上,其他所有事情都被忽略。

Update指示当服务器响应您的请求时将更新哪个元素。

@all:每个组件都被处理/渲染。

@this:处理/呈现带有execute属性的请求组件。

@form:包含请求组件的表单将被处理/呈现。

@parent:包含请求组件的父组件被处理/呈现。

有了Primefaces,你甚至可以使用JQuery选择器,看看这个博客:http://blog.primefaces.org/?p=1867

其他回答

JSF 2.0+关键字

@this当前组件。 @all整个视图。 当前组件的最近祖先形式。 @none没有组件。

JSF 2.3+关键字

@child(n)第n个孩子。 @composite最近的复合组件祖先。 @id(id)通过id搜索组件,忽略组件树结构和命名容器。 当前组件最近的祖先命名容器。 @parent当前组件的父级。 @previous上一个兄弟姐妹。 @next下一个兄弟姐妹。 视图的@root UIViewRoot实例,可以用来从根开始搜索,而不是当前组件。

PrimeFaces特定关键词

@row(n)第n行 带有给定widgetVar的组件。

你甚至可以使用“PrimeFaces Selector”,它允许你使用jQuery Selector API。例如,使用CSS类myClass处理元素中的所有输入:

process="@(.myClass :input)"

See:

https://primefaces.github.io/primefaces/12_0_0/#/core/searchexpression

PrimeFaces 10+观察者/事件

这允许您根据@obs(event)关键字设置的自定义事件名称更新组件。例如:

<p:commandButton update="@obs(myEvent)"/>

<h:panelGroup>
    <p:autoUpdate on="myEvent"/>
</h:panelGroup>

See:

https://www.primefaces.org/showcase/ui/ajax/observer.xhtml

如果你很难记住默认值(我知道我有……)这里是BalusC回答的一个简短摘录:

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

<p:commandXxx进程> <p:ajax进程> <f:ajax execute>

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

JSF will then apply the request values (finding HTTP request parameter based on component's own client ID and then either setting it as submitted value in case of EditableValueHolder components or queueing a new ActionEvent in case of ActionSource components), perform conversion, validation and updating the model values (EditableValueHolder components only) and finally invoke the queued ActionEvent (ActionSource components only). JSF will skip processing of all other components which are not covered by process attribute. Also, components whose rendered attribute evaluates to false during apply request values phase will also be skipped as part of safeguard against tampered requests.

注意,对于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>

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

然后是@all。这对进程属性没有特殊影响,但只对更新属性有特殊影响。process="@all"的行为与process="@form"完全相同。HTML不支持同时提交多个表单。

顺便说一下,如果你完全不需要处理任何东西,但只想通过更新更新某些特定的部分,特别是那些内容不依赖于提交的值或操作侦听器的部分,@none可能会很有用。

Noted should be that the process attribute has no influence on the HTTP request payload (the amount of request parameters). Meaning, the default HTML behavior of sending "everything" contained within the HTML representation of the <h:form> will be not be affected. In case you have a large form, and want to reduce the HTTP request payload to only these absolutely necessary in processing, i.e. only these covered by process attribute, then you can set the partialSubmit attribute in PrimeFaces Ajax components as in <p:commandXxx ... partialSubmit="true"> or <p:ajax ... partialSubmit="true">. You can also configure this 'globally' by editing web.xml and add

<context-param>
    <param-name>primefaces.SUBMIT</param-name>
    <param-value>partial</param-value>
</context-param>

或者,您也可以使用OmniFaces 3.0+的<o:form>,默认为这种行为。

The standard JSF equivalent to the PrimeFaces specific process is execute from <f:ajax execute>. It behaves exactly the same except that it doesn't support a comma-separated string while the PrimeFaces one does (although I personally recommend to just stick to space-separated convention), nor the @parent keyword. Also, it may be useful to know that <p:commandXxx process> defaults to @form while <p:ajax process> and <f:ajax execute> defaults to @this. Finally, it's also useful to know that process supports the so-called "PrimeFaces Selectors", see also How do PrimeFaces Selectors as in update="@(.myClass)" work?


<p:commandXxx更新> <p:ajax更新> <f:ajax渲染>

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

JSF will then prepare the right ajax response for that, containing only the requested parts to update. JSF will skip all other components which are not covered by update attribute in the ajax response, hereby keeping the response payload small. Also, components whose rendered attribute evaluates to false during render response phase will be skipped. Note that even though it would return true, JavaScript cannot update it in the HTML DOM tree if it was initially false. You'd need to wrap it or update its parent instead. See also Ajax update/render does not work on a component which has rendered attribute.

通常,您希望在提交(部分)表单时只更新真正需要在客户端“刷新”的组件。下面的例子通过@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)

虽然这可能工作得很好,但在这个特定的示例中,更新输入和命令组件是不必要的。除非你改变action方法中的模型值foo和bar(这反过来在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选择器是如何工作的?对细节)

@parent只更新父组件,因此它涵盖了当前组件和所有兄弟组件及其子组件。如果你把表单分成了不同的组,每个组都有自己的职责,这就更有用了。@this显然只更新当前组件。通常,只有当您需要在action方法中更改组件自身的HTML属性时才需要这样做。如。

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

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

The @all updates the entire document, which should be used with care. Normally, you'd like to use a true GET request for this instead by either a plain link (<a> or <h:link>) or a redirect-after-POST by ?faces-redirect=true or ExternalContext#redirect(). In effects, process="@form" update="@all" has exactly the same effect as a non-ajax (non-partial) submit. In my entire JSF career, the only sensible use case I encountered for @all is to display an error page in its entirety in case an exception occurs during an ajax request. See also What is the correct way to deal with JSF 2.0 exceptions for AJAXified components?

与特定于PrimeFaces的更新等效的标准JSF从<f:ajax render>呈现。它的行为完全相同,除了它不支持逗号分隔的字符串,而PrimeFaces支持(尽管我个人建议只坚持空格分隔的约定),也不支持@parent关键字。update和render的默认值都是@none(即“nothing”)。


参见:

如何找出组件的ajax更新/渲染客户端ID ?无法找到表达式“foo”从“bar”引用的组件 按PrimeFaces p:commandButton时事件的执行顺序 如何减少请求负载的p:ajax期间,例如p:dataTable分页 如何显示当前行从p:dataTable在一个p:对话框和更新后保存的细节 如何使用<h:形式>在JSF页面?单形式?多种形式?嵌套形式?

通过进程(在JSF规范中称为execute),您告诉JSF将处理限制在指定的组件上,其他所有事情都被忽略。

Update指示当服务器响应您的请求时将更新哪个元素。

@all:每个组件都被处理/渲染。

@this:处理/呈现带有execute属性的请求组件。

@form:包含请求组件的表单将被处理/呈现。

@parent:包含请求组件的父组件被处理/呈现。

有了Primefaces,你甚至可以使用JQuery选择器,看看这个博客:http://blog.primefaces.org/?p=1867

这些是用于提供部分视图处理和部分渲染的PrimeFaces特性。你可以控制在生命周期中执行什么,用ajax渲染什么。

在表达式语言中使用backing bean属性时

进程属性调用SETTER方法 update属性调用GETTER方法

primefaces论坛