如何找出ajax更新/渲染的组件的客户端ID?找不到从“bar”引用表达式“foo”的组件

以下代码源自PrimeFaces DataGrid DataTable教程,并放入一个< p:tab>的< p:tabView>居住在< p:layoutUnit>的< p:layout&gt ;.这里是代码的内部部分(从p:tab组件开始);外部是微不足道的。
<p:tabView id="tabs">
    <p:tab id="search" title="Search">                        
        <h:form id="insTable">
            <p:dataTable id="table" var="lndInstrument" value="#{instrumentBean.instruments}">
                <p:column>
                    <p:commandLink id="select" update="insTable:display" oncomplete="dlg.show()">
                        <f:setPropertyActionListener value="#{lndInstrument}" 
                                        target="#{instrumentBean.selectedInstrument}" />
                        <h:outputText value="#{lndInstrument.name}" />
                    </p:commandLink>                                    
                </p:column>
            </p:dataTable>
            <p:dialog id="dlg" modal="true" widgetVar="dlg">
                <h:panelGrid id="display">
                    <h:outputText value="Name:" />
                    <h:outputText value="#{instrumentBean.selectedInstrument.name}" />
                </h:panelGrid>
            </p:dialog>                            
        </h:form>
    </p:tab>
</p:tabView>

当我点击< p:commandLink&gt ;,代码停止工作,并给出消息:

Cannot find component with expression “insTable:display” referenced from “tabs:insTable:select”.

当我尝试使用< f:ajax&gt ;,它失败了一个不同的消息基本上告诉同样:

<f:ajax> contains an unknown id “insTable:display” cannot locate it in the context of the component “tabs:insTable:select”

这是怎么造成的,我该如何解决呢?

在HTML输出中查找实际的客户端ID

您需要查看生成的HTML输出以找出正确的客户端ID。在浏览器中打开页面,右键单击并查看源代码。找到感兴趣的JSF组件的HTML表示,并将其id作为客户端ID。您可以根据当前命名容器以绝对或相对的方式使用它。请参见以下章节。

注意:如果它恰好包含迭代索引,如:0 :,:1 :,etc(因为它在迭代组件中),那么您需要意识到更新特定的迭代轮并不总是被支持。有关更多详细信息,请参阅答案底部。

记住NamingContainer组件,并始终为它们提供固定的ID

如果你想要由ajax process / execute / update / render引用的组件在同一个NamingContainer父级中,那么只需引用自己的ID。

<h:form id="form">
    <p:commandLink update="result"> <!-- OK! -->
    <h:panelGroup id="result" />
</h:form>

如果它不在同一个NamingContainer内,那么您需要使用绝对客户端ID来引用它。绝对客户端ID以NamingContainer分隔符开头,默认情况下:。

<h:form id="form">
    <p:commandLink update="result"> <!-- FAIL! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
    <p:commandLink update=":result"> <!-- OK! -->
</h:form>
<h:panelGroup id="result" />
<h:form id="form">
    <p:commandLink update=":result"> <!-- FAIL! -->
</h:form>
<h:form id="otherform">
    <h:panelGroup id="result" />
</h:form>
<h:form id="form">
    <p:commandLink update=":otherform:result"> <!-- OK! -->
</h:form>
<h:form id="otherform">
    <h:panelGroup id="result" />
</h:form>

NamingContainer组件例如< h:form>,< h:dataTable>,< p:tabView>,< cc:implementation> (因此,所有复合组件)等。您通过查看生成的HTML输出容易地识别它们,它们的ID将被预先附加到所有子组件的生成的客户端ID。请注意,当它们没有固定的ID时,JSF将使用j_idXXX格式的自动生成的ID。你应该通过给他们一个固定的ID绝对避免。 OmniFaces NoAutoGeneratedIdViewHandler在开发过程中可能对此有所帮助。

如果你知道找到有问题的UIComponent的javadoc,那么你也可以在那里检查它是否实现了NamingContainer接口。例如,HtmlForm(在< h:form>标签后面的UIComponent)显示它实现了NamingContainer,但HtmlPanelGroup(< h:panelGroup>标签后面的UIComponent)不显示它,所以它不实现NamingContainer。 Here is the javadoc of all standard componentshere is the javadoc of PrimeFaces

解决您的问题

所以在你的情况:

<p:tabView id="tabs"><!-- This is a NamingContainer -->
    <p:tab id="search"><!-- This is NOT a NamingContainer -->
        <h:form id="insTable"><!-- This is a NamingContainer -->
            <p:dialog id="dlg"><!-- This is NOT a NamingContainer -->
                <h:panelGrid id="display">

生成的HTML输出< h:panelGrid id =“display”>看起来像这样:

<table id="tabs:insTable:display">

您需要将完全相同的ID作为客户端ID,然后加上:for update in update:

<p:commandLink update=":tabs:insTable:display">

引用外部include / tagfile / composite

如果这个命令链接在一个include / tag文件中,并且目标在其外部,因此你不一定知道当前命名容器的命名容器父的ID,那么你可以通过UIComponent#getNamingContainer )像这样:

<p:commandLink update=":#{component.namingContainer.parent.namingContainer.clientId}:display">

或者,如果此命令链接在复合组件内部,并且目标位于复合组件外部:

<p:commandLink update=":#{cc.parent.namingContainer.clientId}:display">

或者,如果命令链接和目标都在同一复合组件内:

<p:commandLink update=":#{cc.clientId}:display">

参见Get id of parent naming container in template for in render / update attribute

它如何在封面下工作

这一切都在the UIComponent#findComponent() javadoc中被指定为“搜索表达式”:

A search expression consists of either an identifier (which is matched exactly against the id property of a UIComponent,or a series of such identifiers linked by the UINamingContainer#getSeparatorChar character value. The search algorithm should operates as follows,though alternate alogrithms may be used as long as the end result is the same:

  • Identify the UIComponent that will be the base for searching,by stopping as soon as one of the following conditions is met:
    • If the search expression begins with the the separator character (called an “absolute” search expression),the base will be the root UIComponent of the component tree. The leading separator character will be stripped off,and the remainder of the search expression will be treated as a “relative” search expression as described below.
    • Otherwise,if this UIComponent is a NamingContainer it will serve as the basis.
    • Otherwise,search up the parents of this component. If a NamingContainer is encountered,it will be the base.
    • Otherwise (if no NamingContainer is encountered) the root UIComponent will be the base.
  • The search expression (possibly modified in the previous step) is now a “relative” search expression that will be used to locate the component (if any) that has an id that matches,within the scope of the base component. The match is performed as follows:
    • If the search expression is a simple identifier,this value is compared to the id property,and then recursively through the facets and children of the base UIComponent (except that if a descendant NamingContainer is found,its own facets and children are not searched).
    • If the search expression includes more than one identifier separated by the separator character,the first identifier is used to locate a NamingContainer by the rules in the previous bullet point. Then,the findComponent() method of this NamingContainer will be called,passing the remainder of the search expression.

注意,PrimeFaces也遵守JSF规范,但RichFaces使用“some additional exceptions”

“reRender” uses UIComponent.findComponent() algorithm (with some additional exceptions) to find the component in the component tree.

这些额外的异常没有详细描述,但是已知相对组件ID(即不以:)开头的组件ID不仅在最近的父NamingContainer的上下文中被搜索,而且在相同视图中的所有其他NamingContainer组件是一个相对昂贵的工作)。

不要使用prependId =“false”

如果这一切仍然无效,请验证您是否未使用< h:form prependId =“false”>。这将在处理ajax提交和呈现期间失败。另见这个相关问题:UIForm with prependId=”false” breaks <f:ajax render>

引用迭代组件的特定迭代轮次

很长时间以来不可能在迭代诸如< ui:repeat>等组件中引用特定的迭代项。和< h:dataTable>像这样:

<h:form id="form">
    <ui:repeat id="list" value="#{['one','two','three']}" var="item">
        <h:outputText id="item" value="#{item}" /><br/>
    </ui:repeat>

    <h:commandButton value="Update second item">
        <f:ajax render=":form:list:1:item" />
    </h:commandButton>
</h:form>

然而,由于Mojarra 2.2.5的< f:ajax>开始支持它(它只是停止验证它;因此你永远不会面临的问题提到的异常了;以后计划另一个增强修复)。

这只在当前的MyFaces 2.2.7和PrimeFaces 5.2版本中不起作用。该支持可能在未来的版本中。同时,最好的办法是更新迭代组件本身,或者如果它不呈现HTML(例如< ui:repeat>)时的父元素。

使用PrimeFaces时,请考虑搜索表达式或选择器

PrimeFaces Search Expressions允许您通过JSF组件树搜索表达式引用组件。 JSF有几个内置:

> @this:current component
> @form:parent UIForm
> @all:整个文档
> @none:nothing

PrimeFaces通过新的关键字和复合表达式支持增强了这一点:

> @parent:parent component
> @namingcontainer:parent UINamingContainer
> @widgetVar(name):由给定的widgetVar标识的组件

您还可以在复合表达式中混合这些关键字,例如@form:@parent,@this:@parent:@parent等。

PrimeFaces Selectors (PFS)在@(。someclass)允许你通过jQuery CSS选择器语法来引用组件。例如。引用在HTML输出中具有所有通用样式类的组件。这在您需要引用“很多”组件的情况下尤其有用。这只需要目标组件在HTML输出中具有所有客户端ID(固定或自动生成,无所谓)。参见How do PrimeFaces Selectors as in update=”@(.myClass)” work?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


$.AJAX()方法中的PROCESSDATA参数 在使用jQuery的$.ajax()方法的时候参数processData默认为true(该方法为jQuery独有的) 默认情况下会将发送的数据序列化以适应默认的内容类型application/x-www-form-urlencoded 如果想发送不
form表单提交的几种方式 表单提交方式一:直接利用form表单提交 html页面代码: &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;UTF-8&quot; /&gt; &lt;title&gt;Ins
文章浏览阅读1.3k次。AJAX的无刷新机制使得在注册系统中对于注册名称的检测能即时显示。常见的用户注册是用户输入用户名,后台程序检测数据库中用户名是否重复而做出注册的成功与失败之提示(当用户注册重名时将返回重新注册),或者稍微人性化一点就是在用户名文本框后添加一个检测按钮,让用户检测后再做注册。以上操作,对于用户体验方面来说是比较“差劲”的,一个很好的用户体验就是:当用户输入完注册用户名后,Web系统应能即时检查并即时_用户注册 实时异步检测
文章浏览阅读1.2k次。 本文将解释如何使用AJAX和JSON分析器在客户端和服务器之间创建复杂的JSON数据传输层。一、 引言毫无疑问,AJAX已经成为当今Web开发中一种强有力的用户交互技术,但是它的许多可能性应用仍然鲜为人知。在本文中,我们将来共同探讨如何 使用JavaScript对象标志(JSON)和JSON分析器在服务器和客户端AJAX引擎之间创建复杂而强有力的JSON数据传输层。我们将_ajax技术可行性
文章浏览阅读2.2k次。/************************** 创建XMLHttpRequest对象 **************************/function CreateRequest(){ var xmlObj = null; try { xmlObj = new XMLHttpRequest(); } catch(e) {
文章浏览阅读3.7k次。在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖 掉,如果每次都创建一个新的XMLHttpRequest对象,也会造成浪费。解决的办法就是创建一个XMLHttpRequset的对象池,如果池里有 空闲的对象,则使用此对象,否则将创建一个新的对象。下面是我最近写的一个简单的类:* XMLHttpReques_xmlhttprequest发送多个请求
文章浏览阅读3.1k次。Ajax 同一页面如何同时执行多个 XMLHTTP 呢,比如博客页,需要同时利用 Ajax 读取作者信息、文章信息、评论信息……我们的第一反应可能是创建多个全局 XMLHTTP 对象,但这并不现实。其实实现方式非常简单,就是给 onreadystatechange 对应的回调函数加上参数,以下代码是解决方案中一个函数中的一段代码。xmlhttp.open("GET", "ajax_proc_ajax响应多个mxl文件
文章浏览阅读1.5k次。数据岛指的是存在Html网页中的xml代码段,它在Html中形成了一个数据的集合,数据岛允许我们在Html网页中集成xml,对xml编写脚本.数据岛有它特有的形式,由标记xml开始,在开始标记中要有一个ID属性,用于指定该指定数据岛的名称。 (当然要以/xml结束).元素xml包含的内容就是xml代码。数据岛也分为2种:1)内嵌的数据岛形式2)外嵌的数据岛形式说了那么多废话,还_数据中岛计算模式
文章浏览阅读2.1k次。AJAX 流行之后,总想好好学习一下。但是众多的框架实在难以选择。说明一下 ASP.NET AJAX 并不包括在 AJAX 框架之中。刚开始学了 JQuqery, 众多的 $get(),...等等符号早已把我搞晕了。暂时就放弃了。后来学习 ASP.NET AJAX ,在微软的领导下,逐渐由服务器端转向客户端编程。 激起我客户端编程的兴趣,才想起学习一下了 Jquery. 随着WEB2._jquery ajax asp.net 认证
文章浏览阅读1.7k次。前段时间在用google map api的函数库的时候,发现里面的downloadUrl函数非常好用,所以自己写了一个。用腻了那些什么框架什么池,到头来发现越简单的东西越是适合我这种懒人。downloadUrl(url, callback, data);参数说明: url不用说了; callback是回调函数,函数调用的时候会有两个参数:data, responseCode,data就_xmlhttprequest downloadurl
文章浏览阅读956次。前些时间写了几篇关于XMLHTTP运用的实例.(可以到http://dev.csdn.net/user/wanghr100看之前的几编关于XMLHTTP的介绍.)近来看论坛上经常有人提问关于如何无刷新,自动更新数据.传统上,我们浏览网页,如果加入最新的数据.只能是等我们重新向服务器端请求时才能显示出来.但是,对于一些时效性很强的网站.传统的这种做法是不能满足的.我们可以让程序自动刷新.定时_后端xml怎么实现数据有救新增,没有就更新
文章浏览阅读3.3k次。 XMLHttpRequest调用XMLHttpRequest Call ●●●调用,回调,下载,抓取,实时,查询,远程通信(Remoting),远程通信脚本(RemoteScripting),同步,上传,XMLHttpRequest图6-2:XMLHttpRequest调用 目标故事Reta正在一个批发商网站上购买商品。每次她添加一个商品到购物车时,web站点发出_createxmlhttpre
文章浏览阅读1.3k次。function clearitem(){ var drp1 = document.getElementById("drp1"); while(drp1.options.length>0) { drp1.options.remove(0); } }//动态更改方法(根据城市代码取得该市商业区并添加到DropDownList中_dropdownlist根據動態變化
文章浏览阅读1.9k次。因為 Json.net 是有附原始碼的,他也附了單元測試的專案,底下是我額外增加的UnitTest,我的目標就是讓底下的測試可以pass,而且原來的Test 也要都能通過。 ValueTypeTest.csusing System;using NUnit.Framework;namespace Newtonsoft.Json.Test { [TestFixture] public cl_vb 無效的 json 基本型別
文章浏览阅读844次。利用XMLHTTP无刷新获取数据. 客户端和服务器端数据的交互有几种方法.1.提交,通过提交到服务器端.也称"有刷新"吧.2.通过XMLHTTP无刷新提交到服务器端,并返回数据.也称"无刷新"吧.利用XMLHTTP我们可以实现很多很强大的应用.这文章主要介绍它的一些简单的应用.附:因为XMLHTTP是IE5.0+支持的对象.所以你必须要有IE5.0+才能看到效果.client.htm_xmlhttp取源码没有更新
文章浏览阅读1.8k次。Json.Net 無法序列基本型別(string, int),Asp.Net Ajax 無法正確序列日期,AjaxPro序列出我不想要的_type字串 1. Json.Net 是我最常使用的序列/反序列json套件,標榜速度快,對於一對多關係的object 也都能正常運作, 己能滿足我平日的需要,但前幾天突然有個情況,我要序列的是一個泛型參數,該參數不一定是物object型別,有可能是st_token string in state start
文章浏览阅读1.3k次。转载自:http://www.cnblogs.com/JeffreyZhao/archive/2007/01/31/update_the_updatepanels_by_js.html众 所周知,UpdatePanel是通过Trigger来更新的。被设定为Trigger的控件在PostBack之后会被客户端所截获,并且使用 XMLHttpRequest对象发送内容,然后服务器端由ScriptMan_web.ui.updatepanel 和 updatepanel 的区别
文章浏览阅读1.9k次。有些时候,只是需要更新页面的一个部分甚至只是更新中间的几个数据却需要从服务器DOWN整个页面,导致各种资源的浪费。使用数据岛技术可以很好的解决这个问题:通过定时器或用户事件触发数据岛(XML对象)象服务器获取数据,在数据获取完成后,适时更新相关数据。示例HTML部分:http://localhost/WebService/LoadData/FeaturedService.asmx/GetScore_web数据岛
文章浏览阅读1k次。在页面上使用ActiveXObject的代价是很大的,如果我们的无刷新页面使用xmlhttp技术,我们或许需要频繁的建立xmlhttp对象,当然 我们也可以使用全局变量来cache一个xmlhttp对象实例。但是这样的方法适合于同步方式xmlhttp通信,而对于异步方式xmlhttp通信将 会出现问题。由于没有了进程的堵塞,用户可能再次调用同一个xmlhttp实例,如果这时前一个通信未完成,那么就
文章浏览阅读998次。 by Lokesh Dhakar 译: croc查看原文概要:Lightbox JS 是一个简单而又谦恭的用来把图片覆盖在当前页面上的脚本. 它能被快速安装并且运作于所有流行的浏览器.最新更新 Version 2.0 图片集: 分组相关的图片并且能轻松的导航它们 视觉特效: 奇特的自适应调整 向后兼容: yes! 点击这里查看实例_on lightbox 2 by lokesh dhakar