El siguiente código está inspirado en el PrimeFaces DataGrid + DataTable Tutoriales y poner en un <p:tab> de un <p:tabView> que residen en un <p:layoutUnit> de un <p:layout>. Aquí es la parte interna del código (a partir de p:tab componente); la parte exterior es trivial.

<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>

Cuando hago clic en el <p:commandLink>, el código deja de funcionar y da el mensaje:

No se puede encontrar el componente con la expresión «inestable:pantalla» hace referencia de «fichas:inestable:seleccionar».

Cuando yo intente lo mismo con <f:ajax>, se produce un error con un mensaje diferente, básicamente, contando la misma:

<f:ajax> contiene un desconocido id «inestable:pantalla de» no se puede ubicar en el contexto de la componente de «fichas:inestable:seleccione»

Cómo es esto causó y cómo puedo solucionarlo?

OriginalEl autor perissf | 2011-12-26

4 Comentarios

  1. 277

    Buscar en la salida HTML para el real ID de cliente

    Usted necesita para buscar en el código HTML generado salida para encontrar el ID de cliente. Abra la página en el explorador, haga un clic derecho y Ver código Fuente. Busque el código HTML de la representación de la JSF componente de interés y tomar su id como ID de cliente. Se puede utilizar en una absoluta o relativa según la nomenclatura actual de contenedores. Ver el capítulo siguiente.

    Nota: si pasa a contener la iteración índice como :0:, :1:, etc (porque es dentro de una iteración de componente), entonces usted necesita para darse cuenta de que la actualización de una iteración específica de ronda no es siempre compatible. Vea el fondo de la respuesta para más detalles sobre eso.

    Memorizar NamingContainer componentes y siempre les dan un fijo ID

    Si un componente que desea para referencia por ajax proceso/ejecutar/actualización/render está dentro de la misma NamingContainer de los padres, a continuación, sólo de referencia su propio ID.

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

    Si es no dentro de la misma NamingContainer, entonces usted necesita para hacer referencia a ella mediante una absoluta IDENTIFICACIÓN de cliente. Una absoluta IDENTIFICACIÓN de cliente comienza con la NamingContainer carácter separador, el cual es por defecto :.

    <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 componentes son, por ejemplo,<h:form>, <h:dataTable>, <p:tabView>, <cc:implementation> (por lo tanto, todos los componentes de material compuesto), etc. Se reconocen fácilmente por mirar el código HTML generado en la salida, sus ID se antepone a la que genera el ID de cliente de todos los componentes hijos. Tenga en cuenta que cuando no tienen un fijo ID, a continuación, JSF va a utilizar un ID autogenerado en j_idXXX formato. Usted debe evitar absolutamente que dándoles un fijo de IDENTIFICACIÓN. El OmniFaces NoAutoGeneratedIdViewHandler puede ser útil en esta durante el desarrollo.

    Si sabes encontrar el javadoc de la UIComponent en cuestión, entonces usted puede también comprobar en no si se implementa la NamingContainer interfaz o no. Por ejemplo, el HtmlForm (el UIComponent detrás de <h:form> etiqueta) muestra que se implementa NamingContainer, pero la HtmlPanelGroup (el UIComponent detrás de <h:panelGroup> etiqueta) no lo muestra, por lo que no implementa NamingContainer. Aquí está el javadoc de todos los componentes estándar y aquí está el javadoc de PrimeFaces.

    La solución de su problema

    Así que, en su caso, de:

    <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">

    El HTML generado la salida de <h:panelGrid id="display"> se parece a esto:

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

    Usted necesita tomar exactamente que id como ID de cliente y, a continuación, prefijo con : para el uso en update:

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

    Referencia fuera include/tagfile/compuesto

    Si este comando de enlace está dentro de un include/tagfile, y el destino es fuera de ella, y por lo tanto no se conoce el ID del contenedor de nombres de los padres de la actual nomenclatura recipiente, luego dinámicamente puede hacer referencia a ella a través de UIComponent#getNamingContainer() así:

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

    O, si este comando de enlace está dentro de un componente compuesto y el destino es fuera de ella:

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

    O, si tanto el comando de enlace y de destino están dentro del mismo componente compuesto:

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

    Ver también Obtener id de padres contenedor de nombres en la plantilla para el render /actualización de atributo

    Cómo funciona debajo de las cubiertas

    Todo esto se especifica como «la búsqueda de la expresión» en el UIComponent#findComponent() javadoc:

    Un expresión de búsqueda consta de un identificador (que se corresponde exactamente contra la propiedad id de un UIComponent, o una serie de tales identificadores vinculado por el UINamingContainer#getSeparatorChar valor de carácter. El algoritmo de búsqueda deben funciona de la siguiente manera, aunque alternativo alogrithms puede usarse siempre que el resultado final es el mismo:

    • Identificar el UIComponent que será la base para la búsqueda, al parar tan pronto como una de las condiciones siguientes se cumplen:
      • Si la expresión de búsqueda comienza con el carácter separador (llamado un «absoluto» de la búsqueda de la expresión), la base será la raíz UIComponent de el árbol de componentes. El líder de carácter separador será eliminado, y el resto de la expresión de búsqueda será tratado como un «pariente» de la búsqueda de la expresión, como se describe a continuación.
      • De lo contrario, si este UIComponent es un NamingContainer servirá como base.
      • De lo contrario, la búsqueda hasta que los padres de este componente. Si un NamingContainer se encuentra, será la base.
      • De lo contrario (si no NamingContainer es encontrado) la raíz UIComponent será la base.
    • La expresión de búsqueda (posiblemente modificado en el paso anterior) es ahora un «pariente» de la búsqueda de la expresión que se utiliza para localizar el componente (si alguna) que tiene un identificador que corresponda, en el ámbito de aplicación de los componentes de base. El partido se realiza de la siguiente manera:
      • Si la expresión de búsqueda es un identificador simple, este valor es comparado a la propiedad id y, a continuación, de forma recursiva a través de las facetas y los niños de la base UIComponent (excepto que si un descendiente NamingContainer se encuentra, su propia facetas y los niños no son buscados).
      • Si la expresión de búsqueda incluye más de un identificador separados por el carácter separador, el primer identificador se utiliza para localizar un NamingContainer por las reglas en el punto de viñeta anterior. A continuación, el findComponent() método de este NamingContainer será llamado, pasando el resto de la expresión de búsqueda.

    Nota que PrimeFaces también se adhiere a la especificación JSF, pero RichFaces utiliza «algunas excepciones adicionales».

    «procesar» utiliza UIComponent.findComponent() algoritmo (con algunas excepciones adicionales) para encontrar el componente en el árbol de componentes.

    Esas excepciones adicionales son nada detalladamente descrito, pero se sabe que en relación Identificadores de componente (es decir, aquellos que no empiezan con :) no sólo son buscados en el contexto de la más cercana de los padres NamingContainer, sino también en todos los demás NamingContainer componentes en el mismo punto de vista (que es relativamente un trabajo caro, por cierto).

    Nunca use prependId="false"

    Si todo esto aún no funciona, a continuación, compruebe si usted no está utilizando <h:form prependId="false">. Esto se producirá durante el procesamiento, el ajax de presentar y representar. Ver también esta relacionada con la pregunta: UIForm con prependId=»false» breaks <f:ajax render>.

    Referencia iteración específica ronda de la iteración de los componentes

    Fue por largo tiempo no es posible hacer referencia a un determinado iterada elemento en la iteración de los componentes como <ui:repeat> y <h:dataTable> así:

    <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>

    Sin embargo, desde Mojarra 2.2.5 la <f:ajax> comenzó a apoyar a él (ella simplemente dejó de validación, por lo que nunca se enfrentan a los en la pregunta mencionada excepción; otra mejora revisión está prevista para más adelante).

    Esto sólo no funciona, sin embargo en la actual MyFaces 2.2.7 y PrimeFaces 5.2 versiones. El apoyo puede venir en futuras versiones. En el mientras tanto, su mejor apuesta es la actualización de la iteración propio componente, o un padre de familia en caso de no representar HTML, como <ui:repeat>.

    Cuando utilizando PrimeFaces, considerar la Búsqueda de Expresiones o Selectores

    PrimeFaces Expresiones De Búsqueda permite hacer referencia a los componentes a través de JSF componente del árbol de expresiones de búsqueda. JSF tiene varias builtin:

    • @this: componente de corriente de
    • @form: padre UIForm
    • @all: todo el documento
    • @none: nada

    PrimeFaces ha mejorado este con nuevas palabras clave y compuesto expresión de apoyo:

    • @parent: componente primario
    • @namingcontainer: padre UINamingContainer
    • @widgetVar(name): componente identificado por widgetVar

    También se puede mezclar esas palabras clave en material compuesto de expresiones tales como @form:@parent, @this:@parent:@parent, etc.

    PrimeFaces Selectores (PFS) como en @(.someclass) permite hacer referencia a los componentes a través de CSS jQuery selector de sintaxis. E. g. referencia de los componentes de tener todo un estilo común de la clase en el código HTML de salida. Esto es particularmente útil en caso de que usted necesita para hacer referencia a «un montón de» componentes. Esto sólo prerequires que el objetivo de los componentes de todo un ID de cliente en el HTML de salida (fijo o autogenerados, no importa). Véase también ¿Cómo PrimeFaces Selectores como en update=»@(.miclase)» el trabajo?

    Acabo de leer javadoc: docs.oracle.com/javaee/6/api/javax/faces/component/… Desde JSF 2.0 se ha convertido en configurables en lugar de una constante.
    No SEPARATOR_CHAR en desuso? Puede usted dar un ejemplo de cómo llamar a un componente anidado, por ejemplo: context.getViewRoot().findComponent(":inputform" + UINamingContainer.getSeparatorChar(context) + "inputtext" ); También por favor incluya el código xhtml.
    Gracias, nota acerca del fallo de ajax a procesar dentro de la forma con prependId="false" salvó mi día.
    ¿cuál es el significado exacto de ID de cliente como se indica en su explicación? Es el mismo que en JSF -> «El lado del cliente identificador para este componente». cuanto+gracias por tu trabajo.
    Como se indicó en la respuesta, sólo se admite en Mojarra f:ajax.

    OriginalEl autor BalusC

  2. 9

    primera de todas: que yo sepa la colocación de diálogo dentro de un tabview es una mala práctica… es mejor llevarlo a cabo…

    y ahora a tu pregunta:

    lo siento, me tomó algún tiempo para obtener exactamente lo que quería implementar,

    hice en mi web app a mí mismo ahora, y funciona

    como me comentó antes de colocar el p:diálogo fuera del lado de la » p:tabView ,

    salir de la p:diálogo como inicialmente se propuso :

    <p:dialog modal="true" widgetVar="dlg">
        <h:panelGrid id="display">
            <h:outputText value="Name:" />
            <h:outputText value="#{instrumentBean.selectedInstrument.name}" />
        </h:panelGrid>
    </p:dialog>   

    y la p:commandlink debería tener este aspecto (todo lo que hice es cambiar la actualización de atributo)

    <p:commandLink update="display" oncomplete="dlg.show()">
        <f:setPropertyActionListener value="#{lndInstrument}" 
            target="#{instrumentBean.selectedInstrument}" />
        <h:outputText value="#{lndInstrument.name}" />
    </p:commandLink>  

    el mismo funciona en mi web app, y si no funciona para usted , entonces supongo que hay algo mal en el java bean código…

    He actualizado mi pregunta
    Yo lo recomiendo para probar los cambios que escribí en mi respuesta (con la unión y la faces-config y otros…) esto supone para resolver su «INFO: No se puede encontrar compone…»
    De nuevo he tratado de implementar su 2do sugerencia, pero aún no funciona. Abre el cuadro de diálogo, pero no contienen el elemento seleccionado de datos. El registro muestra «No se puede encontrar el componente con el identificador «j_idt31″ a la vista», y yo no soy capaz de depurar nada más que esto.

    OriginalEl autor Daniel

  3. 5

    Es debido a que la ficha es un contenedor de nombres así… su actualización debe ser update="Search:insTable:display" Lo que puede hacer, así es simplemente coloque el diálogo fuera de la forma y, aún dentro de la ficha, a continuación, sería: update="Search:display"

    OriginalEl autor Lyrion

  4. 0

    Intentar cambiar update="insTable:display" a update="display". Yo creo que usted no puede prefijo el número de identificación con el formulario de IDENTIFICACIÓN como eso.

    Muy viejo, pero engañosa respuesta. Consulte BalusC del post anterior, mostrando claramente el prefijo de un componente de la IDENTIFICACIÓN con el adjuntando el formulario de IDENTIFICACIÓN: <h:form id=»formulario»> <p:commandLink update=»:otherform:resultado de»> <!– OK! –> </h:form> <h:form id=»otherform»> <h:panelGroup id=»resultado» /> </h:form>

    OriginalEl autor Mr.J4mes

Dejar respuesta

Please enter your comment!
Please enter your name here