JSF2/PrimeFaces中的命名容器

JSF2/PrimeFaces中的命名容器,jsf,primefaces,Jsf,Primefaces,PrimeFaces中可能的命名容器是什么?当我们想使用update=“:mainForm:maincarcorbian:userNameTextbox”更新表单上的某些UI控件时,为什么需要为Ajax更新调用附加命名容器id 素数面中可能的命名容器是什么 在JSF中,命名容器派生自 当我们想使用update=“:mainForm:maincarcorbian:userNameTextbox”更新表单上的某些UI控件时,为什么需要为Ajax更新调用附加命名容器id 比方说,如果您在页面中添加另一

PrimeFaces中可能的命名容器是什么?当我们想使用
update=“:mainForm:maincarcorbian:userNameTextbox”
更新表单上的某些UI控件时,为什么需要为Ajax更新调用附加命名容器id

素数面中可能的命名容器是什么

在JSF中,命名容器派生自

当我们想使用update=“:mainForm:maincarcorbian:userNameTextbox”更新表单上的某些UI控件时,为什么需要为Ajax更新调用附加命名容器id

比方说,
如果您在页面中添加另一个
,您将得到一个错误,表明您有一个重复的ID。您可以在这里的JavaDoc中查找:

设置此UIComponent的组件标识符(如果有)。组件标识符必须遵守以下语法限制: 不能是长度为零的字符串。 第一个字符必须是字母或下划线(“”)。 后续字符必须是字母、数字、下划线(“”)或破折号(“-”)

。。此外,对您来说重要的是:

指定的标识符在所有组件(包括面)中必须是唯一的,这些组件是最近的祖先UIComponent的后代,UIComponent是NamingContainer,如果没有这样的祖先是NamingContainer,则指定的标识符必须在整个组件树的范围内

这意味着您不能在同一NamingContainer下拥有两个具有相同ID的组件(如果您根本没有NamingContainer,则整个树将计为NamingContainer)。 因此,您需要添加NamingContainer,如

让我们举个例子:

<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进行更新。您指的是哪个用户名文本框,因为有3个

第一个?然后更新用户名文本框

第二个?然后更新container1:userNameTextbox


第三个?在IntelliJ扫描我所有的JAR,查找javax.faces.component.NamingContainer的实现后,更新container2:userNameTextbox

,我发现如下:

来自PrimeFaces 5.3
  • 手风琴板
  • 旋转木马
  • 纵队
  • 数据网格
  • 数据表
  • 数据记录器
  • 数据表
  • 页面
  • 戒指
  • 微妙的
  • 子视图
  • TabView
  • 树形
  • UIData
  • UITabPanel
来自MyFaces2.1
  • HtmlDataTable
  • HtmlForm
  • 乌特里
  • UIForm
在基本面中命名容器 正如我们在书中看到的那样

NamingContainer是一个必须由任何想要成为命名容器的UIComponent实现的接口。命名容器会影响UIComponent.findComponent(java.lang.String)和UIComponent.getClientId()方法的行为

所以,要在PF中找到命名容器,您需要检查
NamingContainer
接口的层次结构。在Eclipse中,您可以通过
NamingContainer
上的Ctrl+T快捷键来实现这一点

在PF 5.3中,例如:
AccordionPanel
Carousel
数据网格
数据列表
数据表
子表
选项卡

命名容器对组件id的影响
  • 默认行为
  • 命名容器为其子组件提供命名范围。所以它总是在他的子id中添加前缀。所以子组件的id是:
    parent\u component\u id.concat(“:”).concat(“component\u id”)
    。 有一个我读过的专业技巧,即使你没有将NamingContainer添加到你的页面中,它总是由JSF自动添加:)这种创建也存在特殊的算法(第11章:构建自定义UI组件->名为“为复合组件创建顶级组件的规则”的框)。当然,当您不设置id时,它将自动生成(例如j_idt234)。因此完整的组件id可能如下所示:“j_idt123:j_idt234:j_idt345”

  • 更改组件名称分隔符(从JSF 2.x开始)
  • 有一种方法可以覆盖默认组件名称分隔符(“:”)。您可以在web.xml中将其定义为名为javax.faces.separator_CHAR的上下文参数。例如:

    <context-param>
        <param-name>javax.faces.SEPARATOR_CHAR</param-name>
        <param-value>-</param-value>
    </context-param>
    
    
    javax.faces.SEPARATOR_CHAR
    -
    
  • UIForm属性“prependId”
  • 为了避免将作用域添加到子组件中,有一个属性(仅在UIForm组件中)。但这不是推荐的解决方案。请参阅

    组件id使用(例如在“更新”、“流程”中)
  • 完整id
  • 您可以使用整个id:“componentParent:component”。不建议这样做(代码将是脆弱的;任何id更改都会导致在许多地方需要更改id)

  • 命名容器的同一级别中的相对ID
  • 在一个命名容器中,您可以使用简单的组件id

  • PrimeFaces搜索表达式框架
  • 如果您不知道这个特性,请查看PrimeFaces文档。PrimeFaces提供了搜索表达式框架和一些非常有用的机制

    你可以按关键字搜索

    关键字是引用组件的更简单方法,它们解析为 这样,如果id更改,则引用不需要更改。 CoreJSF提供了几个关键字,PrimeFaces提供了更多 以及复合表达式支持

    示例:
    @this
    (当前组件)、
    @form
    (最近的祖先形式)、
    @namingcontainer
    (最近的祖先命名容器)、
    @parent
    @widgetVar(名称)
    。 您还可以在相当复杂的路径(复合表达式)中混合这些关键字,例如:
    @form:@parent
    @this:@pare:@pare