2

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

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

问题是新组件未呈现。在渲染响应阶段似乎没有考虑到这个组件。

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

问候,

纪尧姆

4

3 回答 3

2

这对我有用:

持有绑定到 UIComponent 的 Bean,您希望在其下动态添加其他 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;
            }
        }
    }

页面中的代码片段。我动态地将组件添加到<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>

在会话 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;
    }
}
于 2011-03-27T22:13:04.097 回答
2

如果您在 ajax 请求要添加的组件之前知道该解决方案,则此解决方案有效。但是,如果您不知道要添加哪个组件,它就不起作用。

我也许找到了解决方案:

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

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

问候,

纪尧姆

于 2010-04-20T12:08:58.263 回答
1

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

于 2010-04-20T05:16:35.570 回答