提问人:Shardendu 提问时间:8/16/2014 最后编辑:Jasper de VriesShardendu 更新时间:11/24/2022 访问量:309466
了解 PrimeFaces 进程/更新和 JSF f:ajax 执行/渲染属性
Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes
问:
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" />
答:
通过进程(在 JSF 规范中称为 execute),您告诉 JSF 将处理限制为指定的组件,其他所有内容都被忽略。
update 指示当服务器响应您的请求时将更新哪个元素。
@all : 每个组件都经过处理/渲染。
@this:处理/渲染具有 execute 属性的请求组件。
@form :处理/呈现包含请求组件的表单。
@parent:处理/呈现包含请求组件的父组件。
使用 Primefaces,您甚至可以使用 JQuery 选择器,请查看此博客:http://blog.primefaces.org/?p=1867
<p:commandXxx process>
<p:ajax process>
<f:ajax execute>
该属性是服务器端的,只能影响实现 EditableValueHolder
(输入字段)或 ActionSource
(命令字段)的 UIComponent
。该属性使用以空格分隔的客户机 ID 列表告诉 JSF,在提交(部分)表单时,哪些组件必须在整个 JSF 生命周期中进行处理。process
process
然后,JSF 将应用请求值(根据组件自己的客户端 ID 查找 HTTP 请求参数,然后在组件的情况下将其设置为提交值,或者在组件的情况下将新的 ActionEvent
排队),执行转换、验证和更新模型值(仅限组件),最后调用排队(仅限组件)。JSF 将跳过属性未涵盖的所有其他组件的处理。此外,作为防止篡改请求的一部分,其属性在应用请求值阶段的计算结果也将被跳过。EditableValueHolder
ActionSource
EditableValueHolder
ActionEvent
ActionSource
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>
如果表单包含更多您希望在处理中跳过的输入组件,则有时是不可取的,这通常是您想要根据 ajax 侦听器方法中的当前输入组件更新另一个输入组件或某些 UI 部分的情况。也就是说,您不希望其他输入组件上的验证错误阻止执行 ajax 侦听器方法。
然后是 .这在属性上没有特殊效果,而只在属性上。A 的行为与 完全相同。无论如何,HTML 不支持一次提交多个表单。@all
process
update
process="@all"
process="@form"
顺便说一句,如果您绝对不需要处理任何内容,而只想通过更新某些特定部分,尤其是那些内容不依赖于提交的值或操作侦听器的部分,它也可能很有用。@none
update
请注意,该属性对 HTTP 请求有效负载(请求参数的数量)没有影响。这意味着,发送包含在 HTML 表示中的“所有内容”的默认 HTML 行为将不受影响。如果您有一个大型表单,并且希望将HTTP请求有效负载减少到处理中绝对必要的这些,即仅这些被属性覆盖,那么您可以在PrimeFaces Ajax组件中将属性设置为或。您还可以通过编辑和添加来“全局”配置此内容process
<h:form>
process
partialSubmit
<p:commandXxx ... partialSubmit="true">
<p:ajax ... partialSubmit="true">
web.xml
<context-param>
<param-name>primefaces.SUBMIT</param-name>
<param-value>partial</param-value>
</context-param>
或者,您也可以使用 OmniFaces 3.0+ 的 <o:form>
,它默认为此行为。
与特定于 PrimeFaces 的标准 JSF 等效于 。它的行为完全相同,只是它不支持逗号分隔的字符串,而 PrimeFaces 则支持(尽管我个人建议只坚持空格分隔的约定),也不支持关键字。此外,知道默认为 while 和默认为 .最后,了解支持所谓的“PrimeFaces 选择器”也很有用,另请参阅 update=“@(.myClass)” 中的 PrimeFaces 选择器如何工作?process
execute
<f:ajax execute>
@parent
<p:commandXxx process>
@form
<p:ajax process>
<f:ajax execute>
@this
process
<p:commandXxx update>
<p:ajax update>
<f:ajax render>
该属性是客户端属性,可以影响所有 s 的 HTML 表示形式。该属性使用以空格分隔的客户端 ID 列表告诉 JavaScript(负责处理 ajax 请求/响应的 JavaScript),HTML DOM 树中的哪些部分需要更新以响应表单提交。update
UIComponent
update
然后,JSF 将为此准备正确的 ajax 响应,仅包含请求更新的部分。JSF 将跳过 ajax 响应中属性未涵盖的所有其他组件,从而保持响应有效负载较小。此外,在渲染响应阶段,其属性的计算结果将被跳过。请注意,即使它会返回 ,如果 JavaScript 最初是 ,则无法在 HTML DOM 树中更新它。您需要包装它或更新其父级。另请参阅 Ajax update/render does not work on a component which have render attribute.update
rendered
false
true
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
)
虽然这可能工作正常,但在此特定示例中,输入和命令组件的更新是不必要的。除非你改变模型值和内部方法(这在用户体验的角度来看是不直观的),否则更新它们就没有意义了。消息组件是唯一真正需要更新的组件:foo
bar
action
<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选择器如何工作?
仅更新父组件,从而涵盖当前组件以及所有同级组件及其子组件。如果您已将表单分成合理的组,每个组都有自己的责任,这将更有用。显然,更新只是当前组件。通常,仅当您需要在操作方法中更改组件自己的 HTML 属性之一时,才需要这样做。F.D.(英语:F.D.)@parent
@this
<p:commandButton action="#{bean.action}" update="@this"
oncomplete="doSomething('#{bean.value}')" />
想象一下,需要处理 中更改的组件,那么如果组件没有更新,则此构造将不起作用,原因很简单,这是生成的 HTML 输出的一部分(因此其中的所有 EL 表达式都会在渲染响应期间进行评估)。oncomplete
value
action
oncomplete
将更新整个文档,应谨慎使用。通常,您希望通过普通链接 ( 或 ) 或 的 POST 后重定向来代替真正的 GET 请求。在效果上,具有与非ajax(非部分)提交完全相同的效果。在我的整个 JSF 职业生涯中,我遇到的唯一明智的用例是完整地显示错误页面,以防在 ajax 请求期间发生异常。另请参阅处理 AJAXified 组件的 JSF 2.0 异常的正确方法是什么?@all
<a>
<h:link>
?faces-redirect=true
ExternalContext#redirect()
process="@form" update="@all"
@all
与特定于 PrimeFaces 的标准 JSF 等效于 。它的行为完全相同,只是它不支持逗号分隔的字符串,而 PrimeFaces 则支持(尽管我个人建议只坚持空格分隔的约定),也不支持关键字。both 和 默认值为 (即 “nothing”)。update
render
<f:ajax render>
@parent
update
render
@none
另请参阅:
- 如何找出ajax更新/渲染组件的客户端ID?找不到从“bar”引用表达式“foo”的组件
- 按PrimeFaces p:commandButton时事件的执行顺序
- 如何在例如p:dataTable分页期间减少p:ajax的请求有效载荷
- 如何在 p:dialog 中显示 p:dataTable 中当前行的详细信息并在保存后更新
- 如何在JSF页面中使用<h:form>?单一形式?多种形式?嵌套形式?
评论
@this
ActionSource
process="@this"
process
@form
如果你很难记住默认值(我知道我有...),以下是 BalusC 答案的简短摘录:
元件 | 提交 | 刷新 |
---|---|---|
f:阿贾克斯 | 执行=“@this” | 渲染=“@none” |
p:阿贾克斯 | 进程=“@this” | 更新=“@none” |
p:命令XXX | 进程=“@form” | 更新=“@none” |
评论
process
p:commandXXX
@all
p:menuitem
@all
@form
@all
@form
@all
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)"
看:
PrimeFaces 10+ 观察员 / 活动
这允许您根据关键字设置的自定义事件名称更新组件。例如:@obs(event)
<p:commandButton update="@obs(myEvent)"/>
<h:panelGroup>
<p:autoUpdate on="myEvent"/>
</h:panelGroup>
看:
这些是 PrimeFaces 功能,用于提供部分视图处理和部分渲染。您可以控制在生命周期中执行的内容以及使用 ajax 渲染的内容。
在表达式语言中使用后备 Bean 属性时
- process 属性调用 SETTER 方法
- update 属性调用 GETTER 方法
评论