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

Posted

技术标签:

【中文标题】如何在 Ajax 请求期间在 JSF2 中动态添加组件【英文标题】:How to add dynamically a component in JSF2 during an Ajax request 【发布时间】:2011-02-09 03:30:38 【问题描述】:

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

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

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

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

问候,

纪尧姆

【问题讨论】:

【参考方案1】:

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

我也许找到了解决办法:

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

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

问候,

纪尧姆

【讨论】:

这只是一个例子!您可以通过多种方式实现addOutputText()。例如,您可以传递一些扩展类似AbstractComponentFactory 的对象。这个工厂比创建某种UIComponent (public UIComponent AbstractComponentFactory.createComponent())。我希望这是可以理解的。只是需要一些想象力。【参考方案2】:

这对我有用:

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

从页面编码 sn-p。我动态地将组件添加到<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;
    

【讨论】:

【参考方案3】:

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

【讨论】:

实际上,您将如何更改组件的属性(或某些属性)以便在 AJAX 请求期间呈现它?你会使用支持 bean 吗? 您只是希望某些 EL 的评估从 false 变为 true。这可能是一个支持 bean 的布尔属性,或者任何任意复杂的 EL(表达式语言)

以上是关于如何在 Ajax 请求期间在 JSF2 中动态添加组件的主要内容,如果未能解决你的问题,请参考以下文章

JSF 2 - 如何将 Ajax 侦听器方法添加到复合组件接口?

在ajax请求期间处理MVC表单身份验证到期[重复]

如何通过导航菜单 ajax-refresh 动态包含内容? (JSF SPA)

休眠延迟加载的 JSF2 + Ajax EL 问题

Ajax 请求期间出现 500 错误

为啥 JSF 2.2 需要更多时间在 Wildfly 上部分呈现 ajax 请求