【问题标题】:jsf2 ajax update parts based on request parametersjsf2 ajax根据请求参数更新部件
【发布时间】:2011-08-08 05:44:11
【问题描述】:

这个例子有点极端,我想做的不完全是这个,而是更简单地证明我的问题

我有一个页面,有一个简单的 index.xhtml:

<html
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:mc="http://java.sun.com/jsf/composite/mc">
    ...
    <h:panelGroup id="u1" styleClass="unique_container">
        <mc:component1></mc:component1>
    </h:panelGroup>
    <h:panelGroup id="u2" styleClass="unique_container">
        <mc:component2></mc:component2>
    </h:panelGroup>
    <h:panelGroup id="u3" styleClass="unique_container">
        <mc:component3></mc:component3>
    </h:panelGroup>
    <form action="/faces/async.xhtml">
        <input type="checkbox" name="renderu1" />
        <input type="checkbox" name="renderu2" />
        <input type="checkbox" name="renderu1" />
        <input type="submit" value="render" />
    </form>
    ...
</html>

当我按下“GO”按钮时,如果检查了 renderu1,我想渲染 component1,如果检查了 renderu2,我想渲染 component2,如果检查了 renderu3,我想渲染 component3

我目前的解决方案是使用 jQuery 表单插件的 js 函数:

$(document).ready(function(){
    registerForms($(document));
});

function registerForms(rootElement)
{
    rootElement.find("form").submit(function() {
    // submit the form
    $(this).ajaxSubmit(function(data, textStatus) {
        if(textStatus == "notmodified")
            return;


        var tempDiv = $('<div></div>');
        tempDiv.css("display", "none");
        tempDiv.html(data);
        var newUniqueContainer;
        while((newUniqueContainer = tempDiv.find(".unique_container:first")).html() != null)
        {
            var oldUniqueContainer = $("#" + newUniqueContainer.attr("id") + ":first");
            oldUniqueContainer.empty();
            oldUniqueContainer.html(newUniqueContainer.html());
            registerForms(oldUniqueContainer);
            newUniqueContainer.remove();
        }
        tempDiv.remove();
    });
    // return false to prevent normal browser submit and page navigation
    return false;
    });
}

它的作用是每当我提交表单时,它会向给定的 url 触发一个 ajax 请求,等待响应,如果有内容(状态代码不是 304,所以它不是“未修改”),它会得到数据,并将原始“unique_containers”中的内容替换为新数据

async.xhtml:

<html xmlns:mc="http://java.sun.com/jsf/composite/mc"
      xmlns:c="http://java.sun.com/jsp/jstl/core">
    <c:if test="#{asyncBean.render1}">
        <h:panelGroup id="u1" styleClass="unique_container">
            <mc:component1></mc:component1>
        </h:panelGroup>
    </c:if>
    <c:if test="#{asyncBean.render2}">
        <h:panelGroup id="u2" styleClass="unique_container">
            <mc:component2></mc:component2>
        </h:panelGroup>
    </c:if>
    <c:if test="#{asyncBean.render3}">
        <h:panelGroup id="u3" styleClass="unique_container">
            <mc:component3></mc:component3>
        </h:panelGroup>
    </c:if>
</html>

AsyncBean.java:

@ManagedBean(name="asyncBean")
@RequestScoped
public class AsyncBean {

    @ManagedProperty(value="#{param.renderu1}")
    private boolean render1;

    @ManagedProperty(value="#{param.renderu2}")
    private boolean render2;

    @ManagedProperty(value="#{param.renderu3}")
    private boolean render3;

    private boolean isRender1() {
        return render1;
    }

    private void setRender1(boolean render1) {
        this.render1 = render1;
    }

    private boolean isRender2() {
        return render2;
    }

    private void setRender2(boolean render2) {
        this.render2 = render2;
    }

    private boolean isRender3() {
        return render3;
    }

    private void setRender3(boolean render3) {
        this.render3 = render3;
    }
}

因此,例如,如果仅选中第三个复选框,则响应将如下所示:

<html>
    <span id="u3" class="unique_container">
        content of component3
    </span>
</html>

它工作正常,而且很简单,但后来我开始将 RichFaces 用于我的一个组件 - 问题是,它使用 jQuery 的 $(document).ready(fn) 函数,当我重新加载部件时使用 RichFaces,它会中断(它是一个树组件,我无法打开节点)

我一直在寻找一种可行的解决方案,它可以做我的工作,但为兼容性问题做好了更好的准备(从技术上讲,我想根据参数决定要更新的部分,所以当呈现原始页面时,我还不知道要写什么来“执行”和“渲染”属性)

【问题讨论】:

    标签: jquery ajax jsf-2


    【解决方案1】:

    这实际上是一个非常糟糕的解决方案。您可以使用纯 JSF 2.0 解决这个问题,而无需 jQuery、JSTL 和自定义标签。您可以使用&lt;f:ajax&gt; 来触发ajax 请求并呈现部分组件。您可以通过 rendered 属性有条件地渲染 JSF 组件。

    这是一个基本的启动示例,假设您正在运行一个支持 Servlet 3.0 / EL 2.2 的容器,并根据 Servlet 3.0 规范声明了 /WEB-INF/web.xml(否则 .contains() 将无法在 EL 中工作,您必须编写一个自定义 EL 函数)。

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
    >
        ...
        <h:panelGroup id="panels">
            <h:panelGroup rendered="#{bean.panels.contains('u1')}">
                panel one
            </h:panelGroup>
            <h:panelGroup rendered="#{bean.panels.contains('u2')}">
                panel two
            </h:panelGroup>
            <h:panelGroup rendered="#{bean.panels.contains('u3')}">
                panel three
            </h:panelGroup>
        </h:panelGroup>
    
        <h:form>
            <h:selectManyCheckbox value="#{bean.panels}">
                <f:selectItem itemValue="u1" />
                <f:selectItem itemValue="u2" />
                <f:selectItem itemValue="u3" />
                <f:ajax render=":panels" />
            </h:selectManyCheckbox>
        </h:form>
        ...
    </html>
    

    @ManagedBean
    @RequestScoped
    public class Bean {
    
        private List<String> panels;
    
        public List<String> getPanels() {
            return panels;
        }
    
        public void setPanels(List<String> panels) {
            this.panels = panels;
        }
    
    }
    

    就是这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      • 2015-02-11
      • 2016-10-14
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      相关资源
      最近更新 更多