以下代码源自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 components和here 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?

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

  1. HTML5新增form控件和表单属性实例代码详解

    这篇文章主要介绍了HTML5新增form控件和表单属性实例代码详解,需要的朋友可以参考下

  2. HTML5表单验证特性(知识点小结)

    这篇文章主要介绍了HTML5表单验证特性的一些知识点,本文通过实例代码截图的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. amazeui页面分析之登录页面的示例代码

    这篇文章主要介绍了amazeui页面分析之登录页面的示例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  4. ios – Swift Eureka Form中的循环

    我正在构建一个Eureka表单,并希望在表单中放置一个循环来构建基于数组的步进器列表.我试图使用的代码是:但是,当我这样做时,我在StepperRow行上出现了一个错误:所以看起来Swift不再认为它在形式之内并且正在关注

  5. 应用程序关闭时的iOS任务

    我正在构建一个应用程序,通过ajax将文件上传到服务器.问题是用户很可能有时不会有互联网连接,并且客户希望在用户重新连接时安排ajax调用.这可能是用户在离线时安排文件上传并关闭应用程序.应用程序关闭时可以进行ajax调用吗?

  6. 用swift实现navigation bar的完全透明 &amp; navigation bar中button的字体大小调整

    2>或者我们可以来改变这个返回按钮的样式,比如手动把它的文字字体大小调整下注意,因为我们其实是改变的UIBarButtonItem,所以,这段代码我们要放到Appdelegate中来实现。这样,所有的bar中的button类的字体都被强制设定为12号大小了

  7. swift 上传图片和参数 upload image with params

    Alamofire.upload(urlRequest.0,urlRequest.1).progress{(bytesWritten,totalBytesWritten,totalBytesExpectedToWrite)inprintln("\(totalBytesWritten)/\(totalBytesExpectedToWrite)")}}

  8. swift – 如何解开任意类型的可选值?

    给定一个[Any]的数组,其中包含可选值和非可选值,例如:我们如何提取在Any类型(如果有)的Optional的值,所以我们可以创建一个通用打印函数,只打印出值。这个printArray函数遍历并打印每个元素:其中将输出:我们如何更改它,以便它只打印底层值,以便它解包的值,如果它是可选的?将总是解包任何类型。

  9. swift – 从常规方法调用协议默认实现

    我想知道是否可能实现这样的事情。它在某种程度上类似于调用super。类中的方法来满足实现每个属性的需求等,但是我看不到使用struct实现相同的可能性。我不知道你是否仍然在寻找这个答案,但方法是从协议定义中删除该函数,将对象转换为Foo,然后调用它的方法:由于某种原因,它只有在函数未声明为协议的一部分,而是在协议的扩展中定义时才有效。

  10. swift – 使用依赖于其他实例变量的值初始化惰性实例变量

    我已经例如尝试将getEventCalendar从方法转换为函数,但这也无济于事.你可以使用一次只执行的闭包来捕获self的属性并在执行时使用它们.例如.W.r.t.对于你自己的尝试:你可以以同样的方式在这个曾经执行过的闭包中使用self的帮助(实例)函数.

随机推荐

  1. xe-ajax-mock 前端虚拟服务

    最新版本见Github,点击查看历史版本基于XEAjax扩展的Mock虚拟服务插件;对于前后端分离的开发模式,ajax+mock使前端不再依赖后端接口开发效率更高。CDN使用script方式安装,XEAjaxMock会定义为全局变量生产环境请使用xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

  2. vue 使用 xe-ajax

    安装完成后自动挂载在vue实例this.$ajaxCDN安装使用script方式安装,VXEAjax会定义为全局变量生产环境请使用vxe-ajax.min.js,更小的压缩版本,可以带来更快的速度体验。cdnjs获取最新版本点击浏览已发布的所有npm包源码unpkg获取最新版本点击浏览已发布的所有npm包源码AMD安装require.js安装示例ES6Module安装通过Vue.use()来全局安装示例./Home.vue

  3. AJAX POST数据中文乱码解决

    前端使用encodeURI进行编码后台java.net.URLDecoder进行解码编解码工具

  4. Koa2框架利用CORS完成跨域ajax请求

    实现跨域ajax请求的方式有很多,其中一个是利用CORS,而这个方法关键是在服务器端进行配置。本文仅对能够完成正常跨域ajax响应的,最基本的配置进行说明。这样OPTIONS请求就能够通过了。至此为止,相当于仅仅完成了预检,还没发送真正的请求呢。

  5. form提交时,ajax上传文件并更新到&lt;input&gt;中的value字段

  6. ajax的cache作用

    filePath="+escape;},error:{alert;}});解决方案:1.加cache:false2.url加随机数正常代码:网上高人解读:cache的作用就是第一次请求完毕之后,如果再次去请求,可以直接从缓存里面读取而不是再到服务器端读取。

  7. 浅谈ajax上传文件属性contentType = false

    默认值为contentType="application/x-www-form-urlencoded".在默认情况下,内容编码类型满足大多数情况。在这里,我们主要谈谈contentType=false.在使用ajax上传文件时:在其中先封装了一个formData对象,然后使用post方法将文件传给服务器。说到这,我们发现在JQueryajax()方法中我们使contentType=false,这不是冲突了吗?这就是因为当我们在form标签中设置了enctype=“multipart/form-data”,

  8. 909422229_ajaxFileUpload上传文件

    ajaxFileUpload.js很多同名的,因为做出来一个很容易。我上github搜AjaxFileUpload出来很多类似js。ajaxFileUpload是一个异步上传文件的jQuery插件传一个不知道什么版本的上来,以后不用到处找了。语法:$.ajaxFileUploadoptions参数说明:1、url上传处理程序地址。2,fileElementId需要上传的文件域的ID,即的ID。3,secureuri是否启用安全提交,默认为false。4,dataType服务器返回的数据类型。6,error

  9. AJAX-Cache:一款好用的Ajax缓存插件

    原文链接AJAX-Cache是什么Ajax是前端开发必不可少的数据获取手段,在频繁的异步请求业务中,我们往往需要利用“缓存”提升界面响应速度,减少网络资源占用。AJAX-Cache是一款jQuery缓存插件,可以为$.ajax()方法扩展缓存功能。

  10. jsf – Ajax update/render在已渲染属性的组件上不起作用

    我试图ajax更新一个有条件渲染的组件。我可以确保#{user}实际上是可用的。这是怎么引起的,我该如何解决呢?必须始终在ajax可以重新呈现之前呈现组件。Ajax正在使用JavaScriptdocument.getElementById()来查找需要更新的组件。但是如果JSF没有将组件放在第一位,那么JavaScript找不到要更新的内容。解决方案是简单地引用总是渲染的父组件。

返回
顶部