2015-01-16 4 views
1

мне нужно добавить компонент (UIParameter) к компонентуHtmlCommandLink динамически через фазу Listener. Что я хочу достичь, так это то, что каждый элемент <h:link outcome="out"> отображается как <a href="out_url_parsed + ?param=paramvalue">. Где «param» - это мой компонент.Programatically добавить параметр для HtmlCommandLink с использованием фазы Слушатель

Я попытался использовать этот

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. Поэтому я думаю, что поэтому мой добавленный элемент не отображается в конце процесса.

Я уверен, что могу добавить этот параметр для редактирования представлений, но я не хочу этого делать, поскольку он должен присутствовать на всех h: link в приложении и должен присутствовать на любом другом добавленном тоже. Поэтому я считаю это лучший подход, чтобы избежать недостающих тегов

В подобном случае мне удалось добавить входные скрытые элементы в каждой форме на представлении с этим кодом ...

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

Но это Безразлично «т работать на якорных тегах

ответ

2

есть несколько ошибок:

  1. Вы хотите добавить параметр в HtmlCommandLink компонент, который представляет <h:commandLink>, но вы приводите пример с <h:link>, который представлен HtmlOutcomeTargetLink. Что именно вы хотите?

  2. PhaseListener на beforePhase() из RENDER_RESPONSE может быть слишком поздно на запросах GET, которые будут строить только вид впервые во время визуализации ответа. На данный момент у вас будет PhaseListener, у UIViewRoot вообще нет детей. Вместо этого вам лучше зацепить время сборки. Для этого лучше всего подходит SystemEventListener на PostAddToViewEvent.

  3. Вы задаете имя параметра как id вместо name. Используйте UIParameter#setName() вместо UIParameter#setId().

При условии, что вы на самом деле имел в виду, чтобы добавить их к <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); 
    } 

} 

(если вы на самом деле хотите, чтобы применить их на <h:commandLink>, а просто продлить isListenerForSource() чек с || source instanceof HtmlCommandLink)

Для того, чтобы заставить его работать, зарегистрировать его как следует в faces-config.xml:

<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