2010-04-17 2 views
2

В настоящее время я пытаюсь динамически добавлять новый компонент в дерево компонентов JSF во время запроса ajax.Как добавить динамически компонент в JSF2 во время запроса Ajax

Фактически я добавляю ребенка к компоненту UIViewRoot в своем AjaxBehaviorListener, который запускается на стороне сервера во время процесса запроса ajax.

Проблема в том, что новый компонент не отображается. По-видимому, этот компонент не учитывается в фазе ответа рендеринга.

Не могли бы вы мне помочь по этому вопросу?

С уважением,

Гийом

ответ

1

Вместо того, чтобы добавить компонент динамически во время запроса Ajax, попробуйте определения компонент заранее, и это настройка визуализации метки ложь. Содержимое компонента затем может быть заполнено с помощью запроса ajax, а атрибут rendered перевернулся, чтобы отобразить атрибут.

+0

На самом деле, как бы вы изменить атрибут компонента (или какой-либо собственности) чтобы сделать это во время запроса AJAX? Вы использовали бы бэк-бэк? –

+0

Вы просто хотите, чтобы оценка EL изменилась с false на true. Это может быть логическое свойство bean bean bean, или любой произвольно сложный бит EL (язык выражений) –

2

Это решение работает в случае, если вы знаете до того, как запрос ajax добавит компонент. Но если вы не можете узнать, какой компонент добавить, он не работает.

я, возможно, нашел решение:

мое решение реализовать мои пользовательские PartialViewContext и использовать метод startInsertAfter или startInsertBefore из PartialResponseWriter.

Он работает, но вы должны добавить компонент как переходный. (UiComponent.setTransient (Boolean.TRUE);)

С уважением,

Гийом

+0

Это был просто пример! Вы можете реализовать 'addOutputText()' разными способами. Например, вы можете передать какой-то объект, который расширяет нечто вроде 'AbstractComponentFactory'. Эта фабрика чем-то создает 'UIComponent' (' public UIComponent AbstractComponentFactory.createComponent() '). Надеюсь, это понятно. Просто нужно воображение. –

2

Это работает для меня:

Bean проведение связывания с UIComponent, под которым вы хотите добавить другие UIComponents динамически должны быть запрос контекстного в противном случае он может бросить некоторые неприятные исключения (не спрашивайте меня, почему):

@ManagedBean 
    @RequestScoped 
    public class AddressEditorBean { 
// session bean reference for holding id number line and model 
     @ManagedProperty(value = "#{addressValueBean}") 
     private AddressValueBean address;  
     public String addOutputText() { 
      HtmlOutputText text = new HtmlOutputText(); 
      int c = address.getC(); 
      text.setValue("new text! " + c); 
      text.setId("id" + c++); 
      address.setC(c);    // hold id number line in sessionbean 
      address.getComps().add(text); // hold new uicomponent in session bean to be able to rebuild it 
      panel.getChildren().clear(); // need to clear children and add them all again, 
      panel.getChildren().addAll(address.getComps()); // otherwise there are problems with duplicate children (bug?) 
      return "success"; 
     } 

     public HtmlPanelGroup getPanel() { 
      return panel; 
     } 

     public void setPanel(HtmlPanelGroup pane) { 
      if (panel == null) { 
       this.panel = pane; 
       if (panel != null) { 
        panel.getChildren().addAll(address.getComps()); 
       } 
      } else { 
       this.panel = pane; 
      } 
     } 
    } 

фрагмента коды страницы. Я dynnamically добавлять компоненты <h:panelGroup>

<h:form> 
     <h:panelGroup id="section" binding="#{addressEditorBean.panel}"> 

     </h:panelGroup> 
     <h:commandButton value="add new text" action="#{addressEditorBean.addOutputText}"> 
      <f:ajax execute="@this" render="section" event="action"/> 
     </h:commandButton> 
    </h:form> 

В Session Bean я держу фактическую динамическую модель, так что я могу восстановить его после перезагрузки страницы:

@ManagedBean 
@SessionScoped 
public class AddressValueBean extends ValueBean<Address> { 

    private int c = 0; 
    private List<UIComponent> comps = new ArrayList<UIComponent>(); 

    public AddressValueBean() { 
     setValue(new Address()); 
    } 

    public int getC() { 
     return c; 
    } 

    public void setC(int cn) { 
     this.c = cn; 
    } 

    public List<UIComponent> getComps() { 
     return comps; 
    } 

    public void setComps(List<UIComponent> comps) { 
     this.comps = comps; 
    } 
} 
Смежные вопросы