如何在Ajax请求期间动态添加JSF2中的组件

时间:2010-04-17 12:53:12

标签: ajax jsf components dynamic jsf-2

我目前正在尝试在ajax请求期间向JSF组件树动态添加新组件。

实际上我在AjaxBehaviorListener中的UIViewRoot组件中添加了一个子组件,该组件在ajax请求过程中在服务器端触发。

问题是未呈现新组件。似乎在渲染响应阶段不考虑此组件。

你能帮我解决这个问题吗?

此致

纪尧姆

3 个答案:

答案 0 :(得分:2)

此解决方案适用于您在ajax请求添加组件之前知道的情况。 但是,如果您无法知道要添加哪个组件,则无效。

我可能找到了解决方案:

我的解决方案是实现我的自定义PartialViewContext并使用PartialResponseWriter的方法startInsertAfter或startInsertBefore。

它正在运行,但您必须将组件添加为瞬态。 (uiComponent.setTransient(Boolean.TRUE);)

此致

纪尧姆

答案 1 :(得分: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;
            }
        }
    }
来自页面的

代码段。我动态地将组件添加到<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;
    }
}

答案 2 :(得分:1)

不要尝试在ajax请求期间动态添加组件,而是尝试预先定义组件,并将其呈现标记设置为false。然后可以使用ajax请求填充组件的内容,并翻转呈现的属性以显示属性。