2010-06-21 5 views
4

예를 들어 간단한 링크 인 '예미 (prettifier)'와 같은 일종의 작업 매개 변수를 취하는 간단한 복합 구성 요소를 생각해보십시오. 나는 그것을 'ajaxify'하고 싶다.JSF 2.0 복합 구성 요소 - 아약스 렌더링 매개 변수 외부 구성 요소 정의

<composite:interface> 
     <composite:attribute name="act" method-signature="java.lang.String action()"></composite:attribute> 
     <composite:attribute name="text" required="true"></composite:attribute> 
      <composite:clientBehavior name="click" event="action" targets="l"/> </composite:interface> 

    <composite:implementation> 
     <h:commandLink id="l" act="#{cc.attrs.action}" immediate="true">   <b>#{cc.attrs.text}</b>   </h:commandLink> </composite:implementation> 

나는 클라이언트 동작을 통해 이벤트를 노출합니다. 나는이처럼 사용

<h:panelGroup layout="block" id="outside"> 

     #{mybean.otherdata} <br/> 

       <mc:mylink text="Click click" action="#{mybean.click}" > 
        <f:ajax event="click" render="outside"/>" 
       </mc:mylink><br/> 

</h:panelGroup> 

당신은 내가 원하는 것을 볼 수있다 : 나는 아약스가 복합 정의 외부 을 렌더링하고 싶은; render를 "outside"로 설정하면 두려운 <f:ajax> contains an unknown id 오류가 발생합니다.

예, 컨테이너 명명에 대해 알고 있습니다. 콜론을 추가하고 절대 경로를 지정할 수는 있지만 상당히 까다 롭습니다. 만약 내가 몇 가지 더 많은 레이어 (전체 요점이다)에 포장하면 수동으로 함께 이러한 참조를 연결해야 겠어.

구성 요소의 상위 컨테이너에 대한 참조를 건너 뛰려면 render="../outside"과 같은 상대 참조를 만들 수 있습니까?

나는 a4j가있는 jsf 1 앱을 만들었으며이 패턴은 모든 곳에서 사용되었습니다.

+0

'이 패턴은 모든 곳에서 사용되었습니다'라는 말은 a4j가 일치를 찾을 때까지 컨테이너 계층을 올라가는 것처럼 보입니다. 복합 컴포넌트 def는 컴포넌트 경계 – james

답변

1

render="@all" 또는 render="@form"을 사용하여 전체 또는 전체를 렌더링 할 수 있습니다.

또는 매개 변수로 업데이트하려는 항목의 절대 ID를 구성 요소에 전달할 수 있습니다. 이렇게하면 불필요하게 페이지를 너무 많이 렌더링하지 않고 유연성을 유지할 수 있습니다.

이벤트에 리스너를 넣어 :

+0

에서 검색을 종료하는 것으로 보입니다. @all은 작동하지 않습니다. 적어도 mojarra에서는 작동하지 않습니다. @form 않습니다. – james

+1

@all 작동, JBoss AS 7.1.0.CR1b로 테스트되었습니다. 하지만 대부분의 경우 너무 무겁습니다. –

1

는 일부 땜질 한 후, 여기에 하나 개의 솔루션입니다

<f:ajax event="click" listener="#{mycomp.listen}" render="#{mycomp.getParId('outside')}"/>" 

구현 :

public void listen(AjaxBehaviorEvent event) { 
    String clid=event.getComponent().getClientId(); 

    StringTokenizer st=new StringTokenizer(clid,":"); 

    StringBuilder sb=new StringBuilder(":"); 
    for (int x=1;x<st.countTokens();x++) 
    { 
     sb.append(st.nextToken()).append(":"); 
    } 

    parId=sb.toString(); 
} 

public String getParId(String suff) { 
    //must precheck as id is prevalidated for existence. if not set yet set to form 
    if (parId==null) 
    { 
     return "@form"; 
    } 
    return parId+suff; 
} 

는 그럼에도 불구하고, 왜이 작업을 수행해야 할 것?

1

템플릿에서 내재 된 '구성 요소'매핑을 사용하여 내가 만족 스럽다는 더 나은 솔루션을 발견했습니다. ../ 파일 시스템 표기법을 사용하여 복합 컴포넌트에서 기본 상대 매핑을 다시 허용합니다. 더 많은 것을 처리하기 위해 확장 될 수 있지만 필요한 전부입니다. 또한 매개 변수를 실행하기 위해 작동합니다.

나는 그것을 고안해 주셔서 고맙다. 다시, 나는 오해가 무엇입니까? 나는 이것을 알아낼 필요가 없어야한다.

사용법 :

<mc:mylink text="Click me" action="#{blah.myaction}" render="../../pg" /> 

구현 :

<composite:implementation> 

    <h:commandLink id="l" action="#{cc.attrs.action}" immediate="true"> 
     <f:ajax render="#{pathProcessor.pathProcess(3, cc.attrs.render, component.clientId)}" /> 
        #{simon.rand} . <b>#{cc.attrs.text}</b> 
    </h:commandLink> 

..... 

pathprocessor 방법 :

public static String pathProcess(int currentNesting, String path, String clid) { 

    //System.out.println("clientid is "+clid); 
    //System.out.println("path is "+path); 
    //System.out.println("nesting is "+currentNesting); 

    String backTok="../"; 
    String sepchar=":"; 

    StringBuilder src=new StringBuilder(path); 
    int backs=0; 
    int inc=backTok.length(); 

    while (src.indexOf(backTok,backs*inc)==backs*inc) 
    { 
     backs++; 
    } 

    //get rid of the source 
    String suffix=src.substring(backs*inc); 

    //add in internal nesting 
    backs+=(currentNesting-4); 

    StringTokenizer st=new StringTokenizer(clid,sepchar); 

    StringBuilder sb=new StringBuilder(sepchar); 
    for (int x=0;x<st.countTokens()-backs;x++) 
    { 
     sb.append(st.nextToken()).append(sepchar); 
    } 

    //backtracked path 
    String p=sb.toString(); 

    //add suffix to the backtracked client path to get full absolute path 
    String abs=p+suffix; 

    return abs; 
} 

errrr - 뒤를 계산 때 나는 StringBuilder을 사용하는 이유는 모르겠지만 당신은 아이디어를 얻습니다. 그것은 그런 것입니다.

7

JSF 2.0에서는 EL 안에 암시 적 cccomponent 개체를 사용할 수 있습니다. 모든 구성 요소에 대한 전체 클라이언트 ID를 가져 오기 위해 수행

#{component.clientId} 

복합 구성 요소의 클라이언트 ID를 검색하려면 수행

#{cc.clientId} 

같은 방법으로, 당신은 또한 #{cc.parent}와 부모를 가져올 수 있습니다 . 이 경우에, 이것은 아마도 당신이 원하는 것일 것입니다. 좀 더 긴 대답은 Acquire full prefix for a component clientId inside naming containers with JSF 2.0을 참조하십시오.

0

cc.parent.cliendId는 바로 가기 대신 부모 합성 구성 요소를 해결합니다. Obtaining the clientId of the parent of a JSF2 composite component

<composite:interface> 
    <cc:attribute name="render" type="java.lang.String" default="@this"/> 
    <cc:attribute name="action" method-signature="java.lang.String action()"> 
</composite:interface> 

</composite:implementation> 
    <h:form> 
     <h:commandLink action="#{cc.attrs.action}" value="Click"> 
      <f:ajax render="{cc.attr.render}" execute="@form" 
     </h:commandLink> 
    </h:form>  
</composite:implementation> 

그래서 당신은 당신이 렌더링하려고 구성 요소 자체에 의해 결정할 수 있습니다.

<h:panelGroup layout="block" id="outside"> 
    #{mybean.otherdata} 
    <mc:mylink action="#{mybean.click}" render=":outside"/> 
</h:panelGroup>    
관련 문제