在JSF2 / PrimeFaces中命名容器

时间:2012-11-24 17:11:40

标签: jsf primefaces

PrimeFaces中可能的命名容器有哪些?当我们想要使用update=":mainForm:MainAccordian:userNameTextbox"更新表单上的某些UI控件时,为什么有必要为Ajax更新调用添加命名容器ID?

3 个答案:

答案 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实现,这是我发现的:

来自PrimeFaces 5.3

  • AccordionPanel
  • 传送带
  • 数据网格
  • 的DataList
  • DataScroller
  • 数据表
  • 子表
  • 子视图
  • TabView的
  • treetable中
  • UIData
  • UITabPanel

来自MyFaces 2.1

  • HtmlDataTable
  • HtmlForm控件
  • UITree
  • UIForm

答案 2 :(得分:1)

Prime Faces中的命名容器

正如我们在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的影响

  1. 默认行为
  2. 命名容器为其子组件提供命名范围。所以它总是为他的孩子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”。

    1. 更改组件名称分隔符(因为JSF 2.x)
    2. 有一种方法可以覆盖默认的组件名称分隔符(“:”)。您可以在web.xml中将其定义为具有名称javax.faces.SEPARATOR_CHAR的context-param。例如:

      <context-param>
          <param-name>javax.faces.SEPARATOR_CHAR</param-name>
          <param-value>-</param-value>
      </context-param>
      
      1. UIForm属性“prependId”
      2. 为避免向子组件添加范围,有一个属性(仅在UIForm组件中)。但这不是推荐的解决方案。看看例子 uiform-with-prependid-false-breaks-fajax-render

        组件ID用法(例如“更新”,“进程”)

        1. 整个身份
        2. 您可以使用整个id:“componentParent:component”。建议不要这样做(代码会很脆弱;任何id更改都会导致需要在很多地方更改ID。)

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

            1. PrimeFaces搜索表达式框架
            2. 如果您不了解此功能,请查看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)"
              • 更新名为myStyle的styleClass的所有组件

              相当强大的工具。