PrimeFaces中可能的命名容器有哪些?当我们想要使用update=":mainForm:MainAccordian:userNameTextbox"
更新表单上的某些UI控件时,为什么有必要为Ajax更新调用添加命名容器ID?
答案 0 :(得分:16)
Prime面孔中可能的命名容器
在JSF命名容器中派生自UINamingContainer。
当我们想要使用update =“:mainForm:MainAccordian:userNameTextbox”更新表单上的UI控件时,为什么有必要为Ajax更新调用添加命名容器ID
可以说,<h:outputText value="test1" id="userNameTextbox" />
并且您在页面中添加了另一个<h:outputText value="test2" id="userNameTextbox" />
,您将收到一条错误消息,指出您有重复ID 。您可以在JavaDoc中查找UIComponent.setId(String):
设置此UIComponent的组件标识符(如果有)。组件标识符必须遵守以下语法限制: 不能是零长度字符串。 第一个字符必须是字母或下划线('')。 后续字符必须是字母,数字,下划线('')或短划线(' - ')。
..此外,对你很重要:
指定的标识符必须是唯一在作为 NamingContainer 的最近祖先UIComponent的后代的所有组件(包括facet)中,或者在 NamingContainer 的范围内整个组件树,如果没有这样的祖先是NamingContainer。
意味着您不能在同一个NamingContainer下拥有两个具有相同ID的组件(如果您根本没有NamingContainer,则整个树将被视为NamingContainer)。
因此,您需要添加NamingContainer,例如<h:form id="myNamingContainer" />
让我们举个例子:
<h:outputText value="test1" id="userNameTextbox" />
<h:form id="container1">
<h:outputText value="test2" id="userNameTextbox" />
</h:form>
<h:form id="container2">
<h:outputText value="test3" id="userNameTextbox" />
</h:form>
..并且您想要对 userNameTextbox 进行更新。你引用了哪个 userNameTextbox 因为有3个?
第一个?然后更新 userNameTextbox
第二个?然后更新 container1:userNameTextbox
第三个?然后更新 container2:userNameTextbox
答案 1 :(得分:4)
在IntelliJ扫描之后,我发现了javax.faces.component.NamingContainer
的所有JAR实现,这是我发现的:
答案 2 :(得分:1)
正如我们在JSF Reference
中看到的那样NamingContainer是一个必须由任何想要成为命名容器的UIComponent实现的接口。命名容器会影响UIComponent.findComponent(java.lang.String)和UIComponent.getClientId()方法的行为;
因此,要在PF中查找命名容器,您需要检查NamingContainer接口的层次结构。在Eclipse中,您可以通过NamingContainer上的Ctrl + T快捷方式执行此操作。
在PF 5.3中有例如:AccordionPanel,Carousel,Columns,DataGrid,DataList,DataScroller,DataTable,Ring,SubTable,TabView,Tree,TreeTable。
命名容器为其子组件提供命名范围。所以它总是为他的孩子id添加前缀。所以子组件的id是:parent_component_id".concat(":").concat("component_id")
。
我在JavaServer Faces 2.0, The Complete Reference中读到了一个专业提示,即使你没有将NamingContainer添加到你的页面,它总是由JSF本身自动添加:)还有这种创建的特殊算法(第11章:构建自定义UI)组件 - &gt;框称为“为复合组件创建顶级组件的规则”。当然,当你没有设置id时,它会自动生成(例如j_idt234)。所以完整的组件ID可能如下所示:“j_idt123:j_idt234:j_idt345”。
有一种方法可以覆盖默认的组件名称分隔符(“:”)。您可以在web.xml中将其定义为具有名称javax.faces.SEPARATOR_CHAR的context-param。例如:
<context-param>
<param-name>javax.faces.SEPARATOR_CHAR</param-name>
<param-value>-</param-value>
</context-param>
为避免向子组件添加范围,有一个属性(仅在UIForm组件中)。但这不是推荐的解决方案。看看例子 uiform-with-prependid-false-breaks-fajax-render
您可以使用整个id:“componentParent:component”。建议不要这样做(代码会很脆弱;任何id更改都会导致需要在很多地方更改ID。)
在一个命名容器中,您可以使用简单的组件ID。
如果您不了解此功能,请查看PrimeFaces文档。 Prime Faces为搜索表达式框架提供了几种非常有用的机制。
您可以按关键字进行搜索。
关键字是引用组件的更简单方法,它们可以解决这些问题 id,以便在id更改时,引用不需要更改。 Core JSF提供了几个关键字,PrimeFaces提供了更多关键字 以及复合表达支持。
示例:@this(当前组件),@ form(最近的祖先形式),@ Namingcontainer(最近的祖先命名容器),@ parent,@ wedVar(name)。 您也可以在非常复杂的路径(复合表达式)中混合这些关键字,例如:@form:@ parent,@ this:@parent:@parent
第二个可能性PF为您提供PrimeFaces选择器(PFS)。
PFS将jQuery Selector API与JSF组件引用集成在一起 模型,以便可以使用jQuery Selector API完成引用 而不是基于核心id的JSF模型。
所以你可以举例如:
update="@(form)"
update="@(.ui-datatable)"
update="@(.myStyle)"
相当强大的工具。