source

Ajax 업데이트/렌더 컴포넌트의 클라이언트 ID를 확인하는 방법식 "foo"가 "bar"에서 참조되는 구성 요소를 찾을 수 없습니다.

factcode 2023. 3. 15. 19:58
반응형

Ajax 업데이트/렌더 컴포넌트의 클라이언트 ID를 확인하는 방법식 "foo"가 "bar"에서 참조되는 구성 요소를 찾을 수 없습니다.

는 PrimeFaces + PrimeFaces DataGrid + DataTable에 되었습니다.<p:tab><p:tabView><p:layoutUnit><p:layout>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>이 코드는 동작을 정지하고 다음 메시지를 표시합니다.

"tabs:insTable:select"에서 참조된 "insTable:display" 식의 구성 요소를 찾을 수 없습니다.

<f:ajax>이 경우 기본적으로 다음과 같은 다른 메시지가 표시되며 실패합니다.

<f:ajax>ID " 수 .

Ajax 가 "Ajax"로 Development다음 메시지와 함께 JavaScript 경보에 실패합니다.

부정한 X형식ML: 업데이트 중: insTable: 디스플레이를 찾을 수 없음

원인은 무엇이며, 어떻게 해결할 수 있습니까?

HTML 출력에서 실제 클라이언트 ID 검색

생성된 HTML 출력을 조사하여 올바른 클라이언트 ID를 찾아야 합니다.브라우저에서 페이지를 열고 마우스 오른쪽 버튼을 클릭한 후 소스 보기를 수행합니다.관심 있는 JSF 컴포넌트의 HTML 표현을 찾아 그것을 취합니다.id아이디현재 이름 지정 컨테이너에 따라 절대 또는 상대적인 방법으로 사용할 수 있습니다.음음

" "와 같은 되어 있는 : " " "는 " "와 같은 반복 인덱스를 합니다.:0:,:1:(반복 컴포넌트 내에 있기 때문에) 특정 반복 라운드의 갱신이 항상 서포트되고 있는 것은 아닙니다.자세한 내용은 답변 하단을 참조하십시오.

NamingContainer 및 ID를합니다.

ajax 프로세스/실행/업데이트/렌더에서 참조할 구성 요소가 동일한 상위 구성 요소 내에 있는 경우 해당 구성 요소의 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가의 자동 생성 합니다.j_idXXX포맷합니다.당신은 그들에게 고정 아이디를 주어서 절대 그것을 피해야 합니다.옴니페이스는 개발 중에 도움이 될 수 있습니다.

UIComponent여기서 인터페이스를 실장하고 있는지 아닌지를 확인할 수도 있습니다.예를 들어 (the)UIComponent의 배후에<h:form>tag는, 태그의 을 나타내고 있습니다.NamingContainer단, (the (the)UIComponent의 배후에<h:panelGroup>tag되지 않기 에, 는 실장되지 ).NamingContainer모든 표준 컴포넌트의 javadocPrimeFaces의 javadoc입니다.

문제 해결

고객의 경우:

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

<h:panelGrid id="display">음음음같 뭇매하다

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

그 것을 .id한 후 ID로 지정합니다.:의 는,update:

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

외부 포함/태그 파일/복합 참조

파일 파일 에 있기 가 없는 include/tag를 통해 할 수 .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">

자세한 내용은 렌더/업데이트 속성의 템플릿에서 상위 이름 컨테이너 ID 가져오기

이불 속에서 어떻게 작동합니까?

이 모든 것이 javadoc에서 "search expression"으로 지정됩니다.

검색 표현식은 식별자 중 하나로 구성됩니다(이 식별자는 ID 속성과 정확히 일치함).UIComponentUINamingContainer#getSeparatorChar단, 할 수 .검색 알고리즘은 다음과 같이 동작해야 합니다.단, 최종 결과가 같은 한 대체 alogrithms를 사용할 수 있습니다.

  • UIComponent다음 조건 중 하나가 충족되는 즉시 중지함으로써 검색의 기반이 됩니다.
    • 이라고 함)로, 입니다.UIComponent는 삭제되고 "됩니다.선행 구분 문자는 제거되고, 나머지 검색 표현식은 아래 설명과 같이 "상대적" 검색 표현식으로 처리됩니다.
    • 이외의 「」가 .UIComponent는 입니다.NamingContainer★★★★★★★★★★★★★★★★★★★★★★★★★★★
    • 그렇지 않으면 이 구성 요소의 부모를 검색하십시오.「」의 'NamingContainer이 검출되면, 베이스가 됩니다.
    • 않은 경우('아니오'인 )NamingContainer이되다.UIComponent베이스가 됩니다.
  • 검색 표현식(이전 단계에서 수정되었을 수 있음)은 이제 기본 구성 요소의 범위 내에서 일치하는 ID를 가진 구성 요소(있는 경우)를 찾는 데 사용되는 "상대적인" 검색 표현식이 됩니다.일치는 다음과 같이 실행됩니다.
    • 이 후 id id id ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad ad of of of of of of the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the the theUIComponent(하위)인 경우 )NamingContainer검출되어 그 자신의 면과 아이는 검색되지 않습니다).
    • 가 여러 개되어 있는 첫 번째 ,, 음음 음음 음음 음음 음음 음음 음음 음음 음음 음 a 음 a 음 a 음 a 음 a 음 a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a aNamingContainer 후, 「 」는, 「 」를 참조해 주세요.findComponent() 방법NamingContainer검색식의 나머지 부분을 전달하면서 호출됩니다.

PrimeFaces도 JSF 사양을 준수하지만 RichFaces는 "일부 추가 예외"를 사용합니다.

「렌더」의 용도UIComponent.findComponent()알고리즘(일부 추가 예외 포함)을 사용하여 컴포넌트 트리에서 컴포넌트를 찾습니다.

추가 , 컴포넌트 ,하지 않는 가 있는 :는 가장 되는 것이 .NamingContainer 그러나 모든 입니다.NamingContainer같은 뷰의 컴포넌트(그건 그렇고 비교적 비용이 많이 드는 작업입니다)

사용하지 .prependId="false"

안 하세요.<h:form prependId="false">. 이것은 ajax 제출 및 렌더 처리 중에 실패합니다.관련 질문도 참조해 주세요.prependId="false" breaks <f:darender >가 설정된 UIForm입니다.

특정 반복 라운드의 반복 구성 요소 참조

반복적인 구성 에서 특정 할 수 없었습니다.<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>

.2로는 Mojarra 2.2.5.<f:ajax>는, 서포트를 개시했습니다(검증을 정지했을 뿐입니다.따라서, 전술한 질문의 예외에 직면하는 일은 없습니다.이것에 대해서는, 나중에 다른 확장 수정이 예정되어 있습니다).

MyFaces 2.2.7 PrimeFaces 5.2 입니다.이 지원은 향후 버전에서 제공될 수 있습니다. 이 자체를 컴포넌트를 .또한 HTML을 렌더링하지 않는 경우에는 상위 컴포넌트를 갱신하는 것입니다.<ui:repeat>.

PrimeFaces를 사용할 경우 식 또는 선택기 검색 고려

PrimeFaces 검색식을 사용하면 JSF 구성 요소 트리 검색식을 통해 구성 요소를 참조할 수 있습니다.JSF에는 몇 가지 빌트인이 있습니다.

  • @this 컴포넌트: "Current Component" (컴포넌트)
  • @form : 부 :UIForm
  • @all : " " "
  • @none도 아니다: : 、 : 、 : 、 : : : 。

PrimeFaces는 새로운 키워드와 복합 표현 지원을 통해 이 기능을 강화했습니다.

  • @parent 컴포넌트: " " " "
  • @namingcontainer : 부 :UINamingContainer
  • @widgetVar(name) (된 컴포넌트).widgetVar

하면 '어느끼다느니 하다느니 하는 도 있습니다.@form:@parent,@this:@parent:@parent 등등.

PrimeFaces Selector(PFS)같이@(.someclass)를 사용하면 jQuery CSS 셀렉터 구문을 통해 컴포넌트를 참조할 수 있습니다.예를 들어 HTML 출력에 공통 스타일클래스가 있는 컴포넌트를 참조할 수 있습니다.이것은 "많은" 컴포넌트를 참조할 필요가 있는 경우에 특히 도움이 됩니다.이것은, 타겟 컴퍼넌트가 HTML 출력의 모든 클라이언트 ID 를 가지는 것을 전제로 하고 있을 뿐입니다(고정 또는 자동 생성은 상관없습니다).자세한 내용은 업데이트="@(.myClass)"와 같은 PrimeFaces Selector의 작동 방식을 참조하십시오.

우선: 탭 뷰에 대화상자를 배치하는 것은 좋지 않은 방법이라는 것을 알고 있습니다.빼는 게 좋을 거야

이제 질문을 드리겠습니다.

미안, 네가 정확히 구현하고 싶은 걸 얻는데 시간이 좀 걸렸어

방금 내 웹 앱에서 직접 했는데, 작동했어.

앞서 말한 것처럼 p:dialog를 p:tabView의 바깥쪽에 배치합니다.

처음에 제안한 대로 p:dialog를 그대로 둡니다.

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

p:commandlink는 다음과 같습니다(업데이트 속성을 변경한 것 뿐입니다).

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

내 웹 앱에서도 똑같이 동작하고, 만약 그것이 당신에게 효과가 없다면, 당신의 자바 빈 코드에 뭔가 문제가 있는 것 같습니다.

...는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.update="Search:insTable:display" 대화 탭 됩니다. 즉, 대화 상자는 밖에 있고 탭 안쪽에 있으면 .update="Search:display"

PrimeFaces 10 이상에서는 옵서버와 이벤트를 사용할 수 있습니다.

할 수 .은 커스텀이벤트명으로 설정되어 있습니다.@obs(event)키워드를 지정합니다.예를 들어 다음과 같습니다.

<p:commandButton update="@obs(myEvent)"/>

<h:panelGroup>
    <p:autoUpdate on="myEvent"/>
</h:panelGroup>

참조:

BalusC의 훌륭한 답변은 이미 알고 있습니다만, 여기 컨테이너에 올바른 clientId를 알려주기 위해 사용하는 작은 트릭이 있습니다.

  1. 동작하지 않는 컴포넌트의 업데이트를 삭제합니다.
  2. 업데이트하려는 구성 요소 내에 가짜 업데이트가 포함된 임시 구성 요소를 넣습니다.
  3. 페이지를 누르면 servlet 예외 오류가 참조해야 하는 올바른 클라이언트 ID를 알려줍니다.
  4. 가짜 컴포넌트를 삭제하고 원래 업데이트에 올바른 clientId를 추가합니다.

여기 코드 예가 있습니다. 내 말로 표현할 수 없을지도 모르기 때문입니다.

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

이 구성 요소 내에서 실패한 업데이트 제거

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

업데이트에 실패한 업데이트를 사용하여 업데이트하려는 ID의 구성 요소 내에 구성 요소를 추가합니다.

   <p:commandButton id="BogusButton" update="BogusUpdate"></p:commandButton>

                    <h:outputText value="Name:" />
                    <h:outputText value="#{instrumentBean.selectedInstrument.name}" />
                </h:panelGrid>
            </p:dialog>                            
        </h:form>
    </p:tab>
</p:tabView>

이 페이지를 클릭하여 오류를 확인하십시오.에러는 javax.servlet 입니다.ServletException:에서 참조하는 "BogusUpdate" 식에 대한 구성 요소를 찾을 수 없습니다.insTable: BogusButton

따라서 사용하는 올바른 clientId는 굵은 글씨와 타깃컨테이너의 ID가 됩니다(이 경우 표시).

tabs:insTable:display

해 보다update="insTable:display"로로 합니다.update="display"아이디 앞에 폼 아이디를 붙일 수 없다고 생각합니다.

언급URL : https://stackoverflow.com/questions/8634156/how-to-find-out-client-id-of-component-for-ajax-update-render-cannot-find-compo

반응형