2015-01-16 8 views
1

를 사용 HtmlCommandLink하는 매개 변수를 추가합니다. 달성하고자하는 모든 요소는 <h:link outcome="out"><a href="out_url_parsed + ?param=paramvalue">으로 렌더링됩니다. "param"은 내 구성 요소입니다.는, 프로그램 나는 dinamically 위상 리스너를 통해 <strong>HtmlCommandLink</strong> 구성 요소에 구성 요소 (<strong>UIParameter</strong>)를 추가 할 필요가 단계 리스너

나는이

private void addElement(final PhaseEvent event, final Class clazz, final UIComponent component) { 
    final FacesContext fcontext = event.getFacesContext(); 
    UIViewRoot root = fcontext.getViewRoot(); 
    if (root == null) { 
     return; 
    } 

    root.visitTree(new FullVisitContext(fcontext), new VisitCallback() { 

     @Override 
     public VisitResult visit(VisitContext context, UIComponent target) { 
      if (clazz.isInstance(target)) { 
       LOGGER.info("Element Found"); 
       UIParameter parameter = new UIParameter(); 
       parameter.setValue("willberonadom"); 
       parameter.setId("sessiontoken"); 
       target.getChildren().add(parameter); 

      } 
      return VisitResult.ACCEPT; 
     } 
    }); 
} 

를 사용하여 시도했다 그러나 그것은 작동하지 않습니다. 요소는 실제로 트리에서 발견되지만 UIParameter는 렌더링되지 않습니다.

나는 UIViewRoot가 RENDER_RESPONSE 단계 이후에 하위 요소 만 가질 수 있다는 것을 발견했습니다. 그래서 이것이 내가 추가 한 요소가 프로세스가 끝날 때 렌더링되지 않는 이유라고 생각합니다.

필자는 뷰를 편집하는이 param을 추가 할 수 있다고 확신하지만, 응용 프로그램의 모든 h : link에 있어야하고 다른 새로운 것도 추가해야하기 때문에이 작업을 수행하고 싶지 않습니다. 그래서 ... 태그

나는이 코드를보기에 모든 형태의 입력 숨겨진 요소를 추가 관리했습니다 유사한 경우에

누락

HtmlInputHidden hiddenToken = new HtmlInputHidden(); 
hiddenToken.setId("sessiontoken"); 
hiddenToken.setValue("willberandom"); 
hiddenToken.setRendered(true); 
root.addComponentResource(event.getFacesContext(), hiddenToken,"form"); 

을 방지하기 위해 더 나은 방법으로이 문제를 고려하지만, 아무튼 앵커 태그에 't 작업

답변

2

몇 가지 실수가 있습니다

  1. 당신은를 나타내는 HtmlCommandLink 구성 요소에 매개 변수를 추가 할이지만 <h:link>이라는 예는 HtmlOutcomeTargetLink으로 표시됩니다. 정확히 무엇을 원하니? RENDER_RESPONSEbeforePhase()

  2. PhaseListener는 응답 렌더링 중 처음으로 에 대한 뷰를 구축 할 것 GET 요청에 너무 늦을 수 있습니다. PhaseListener이 실행되는 즉시 UIViewRoot에는 어린이가 전혀 없습니다. 대신보기 빌드 시간에 푹 빠져야합니다. 이를 위해서는 SystemEventListener (PostAddToViewEvent)이 가장 적합합니다.

  3. 매개 변수 이름을 name 대신 id으로 설정하고 있습니다. 대신 UIParameter#setName()을 사용하십시오.

는 당신이 실제로 <h:link> 구성 요소에 추가하는 의미가 제공, 여기에 당신이 SystemEventListener와 그것을 달성 할 수있는 방법 킥오프 예입니다.

public class YourSystemEventListener implements SystemEventListener { 

    @Override 
    public boolean isListenerForSource(Object source) { 
     return source instanceof HtmlOutcomeTargetLink; 
    } 

    @Override 
    public void processEvent(SystemEvent event) throws AbortProcessingException { 
     UIParameter parameter = new UIParameter(); 
     parameter.setName("sessiontoken"); 
     parameter.setValue("willberonadom"); 
     ((UIComponent) event.getSource()).getChildren().add(parameter); 
    } 

} 

는 실행 faces-config.xml에 다음과 같이 등록을 얻기 위해

(실제로뿐만 아니라 <h:commandLink>에 적용 할 경우, 단지 || source instanceof HtmlCommandLinkisListenerForSource() 확인을 확장) :

<application> 
    <system-event-listener> 
     <system-event-listener-class>com.example.YourSystemEventListener</system-event-listener-class> 
     <system-event-class>javax.faces.event.PostAddToViewEvent</system-event-class> 
    </system-event-listener> 
</application> 
+0

감사합니다! 그것은 포인트 1과 3에서 작동했습니다. 저는 실제로 다른 요소로 디버깅을하고 있었기 때문에 HtmlCommandLink 타입의 또 다른 요소가 있었고 Id 대신에 이름을 설정하여 작업을 수행했습니다. 모든 것이 작동하기 때문에 나는 두 번째 요셉을 따라갈 것입니다. ') – Oscar

+1

당신을 진심으로 환영합니다. – BalusC