简体   繁体   English

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

[英]How to add dynamically a component in JSF2 during an Ajax request

I am currently trying to dynamically add a new component to the JSF component tree during an ajax request. 我目前正在尝试在ajax请求期间向JSF组件树动态添加新组件。

In fact I add a child to the UIViewRoot component in my AjaxBehaviorListener which is fired on server side during the ajax request process. 实际上,我在AjaxBehaviorListener的UIViewRoot组件中添加了一个子组件,该子组件在ajax请求过程中在服务器端触发。

The issue is that the new component is not rendered. 问题是没有呈现新组件。 It seems that this component is not taken into account in the render response phase. 似乎在渲染响应阶段未考虑此组件。

Could you help me on this issue ? 您能在这个问题上帮助我吗?

Regards, 问候,

Guillaume 纪尧姆

This solution works in case of you know before the ajax request the component to add. 如果您在ajax请求组件添加之前就知道该解决方案,则可以使用该解决方案。 But if you are not able to know which component to add, it does not work. 但是,如果您不知道要添加哪个组件,则它将不起作用。

I maybe found a solution : 我也许找到了解决方案:

My solution is to implement my custom PartialViewContext and use the method startInsertAfter or startInsertBefore of the PartialResponseWriter. 我的解决方案是实现我的自定义PartialViewContext并使用PartialResponseWriter的startInsertAfter或startInsertBefore方法。

It is working, but you have to put the component added as transient. 它正在工作,但是您必须将添加的组件作为瞬态。 (uiComponent.setTransient(Boolean.TRUE);) (uiComponent.setTransient(Boolean.TRUE);)

Regards, 问候,

Guillaume 纪尧姆

This works for me: 这对我有用:

Bean holding binding to UIComponent under which you want to add other UIComponents dynamically should be request scoped otherwise it can throw some nasty exceptions (don't ask me why): Bean绑定到要动态添加其他UIComponent的UIComponent时,应将其范围限制为请求范围,否则它可能会引发一些令人讨厌的异常(不要问我为什么):

   @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;
            }
        }
    }

code snippet from page. 页面中的代码段。 I dynnamically add components to <h:panelGroup> 我动态地将组件添加到<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>

In Session bean I hold actual dynamic model so that I can rebuild it after page reload: 在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;
    }
}

Instead of trying to add the component dynamically during the ajax request, try defining the component upfront, and setting it's rendered tag to false. 与其尝试在ajax请求期间动态添加组件,不如尝试预先定义组件并将其渲染标记设置为false。 The contents of the component can then be populated with the ajax request, and the rendered attribute flipped to display the attribute. 然后,可以使用ajax请求填充组件的内容,并且将呈现的属性翻转以显示该属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM