使用JSF与PrimeFaces构建页面时,如何从流程中排除组件?
根据你的页面结构(嵌套了<p:tabView>的表单,通过<ui:include>引入子页面并传递控制器参数),下面是几种常见的“从流程中排除组件”的解决方案,涵盖不同的业务需求场景:
1. 完全不渲染组件(彻底排除生命周期参与)
如果希望某个组件完全不生成HTML,也不参与JSF的任何生命周期阶段(验证、模型更新等),直接给目标组件添加rendered属性并设为false即可。
比如你要排除tabThemeFormation.xhtml里的一个输入框:
<h:inputText value="#{ficheFormaCtrl.someValue}" rendered="#{false}" />
你也可以用控制器里的布尔值来动态控制:
<h:inputText value="#{ficheFormaCtrl.someValue}" rendered="#{not ficheFormaCtrl.excludeThisComponent}" />
因为你已经通过<ui:include>传递了控制器参数,所以子页面里的EL可以直接访问到ficheFormaCtrl的属性。
2. 表单提交时排除指定组件(保留渲染但不处理)
如果组件需要显示在页面上,但不想让它参与表单提交的处理(比如不验证、不更新模型),可以在提交按钮上用PrimeFaces支持的process属性结合exclude语法来指定要排除的组件。
比如你的提交按钮在主页面,要排除第二个标签页里的所有组件:
<p:commandButton value="提交" action="#{editFormCatalogueFormationController.save}" process="@form exclude(:form:tab:tab2)" />
这里的:form:tab:tab2是第二个标签页的客户端ID(需要和你的实际ID对应,比如如果第二个tab的id是tabFiche,那客户端ID就是:form:tab:tabFiche)。
如果只想排除子页面里的某个特定组件,比如tabFicheFormation.xhtml里的一个下拉框:
<p:commandButton value="提交" action="#{editFormCatalogueFormationController.save}" process="@form exclude(:form:tab:tabFiche:myDropdown)" />
3. 禁用组件(不可交互但保留渲染)
如果只是想让组件不可操作,但仍保留在页面上展示,可以用disabled="true"属性:
<p:inputText value="#{ficheFormaCtrl.someValue}" disabled="true" />
不过要注意:禁用的组件仍会被提交到服务器,但JSF不会更新它对应的模型值。如果要彻底排除提交,建议结合上面的process排除方法。
4. 设置组件为只读(输入组件专用)
对于输入类组件,还可以用readonly="true"让它不可编辑,同时提交时不会更新模型:
<p:inputText value="#{ficheFormaCtrl.someValue}" readonly="true" />
这种方式比disabled更友好,组件样式通常是可选中但不可编辑的状态。
额外提示:动态标签页的特殊处理
如果你的<p:tabView>设置了dynamic="true",未激活的标签页里的组件默认不会被渲染,也就自然不会参与流程。但如果需要在激活状态下也排除某些组件,还是用上面的方法。
内容的提问来源于stack exchange,提问作者idirene youcef

