jsf2形式与ajax

时间:2013-05-23 12:59:42

标签: ajax jsf-2 standards

在复杂的数据输入表单中,可能需要编辑表单中的表单。由于这在JSF2中是不可能的,我想知道对于这个问题可以找到更好的解决方案。这是我需要的一个例子:

  • 给出:两个bean:OuterBean和HobbyBean;在OuterBean中使用了HobbyBeans列表
  • OuterBean是ManagedBean(在SessionScope中)
  • HobbyBean包含两个字段的爱好,比如

我想在OuterBean中添加用户名的形式添加HobbyBeans,而不提交OuterBean但提交新值来填充列表。这是代码示例:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
    </h:head>
    <h:body>
        <h:form>
        <h:panelGrid columns="2">
            <h:outputText value="Name" />
            <h:inputText value="#{outerBean.name}" required="true" />
            <h:outputText value="Hobbies" />
            <h:dataTable id="ht" value="#{outerBean.hobbies}" var="h">
                <h:column>
                    <h:outputText value="#{h.hobby}" />
                    <f:facet name="footer">
                        <h:inputText value="#{outerBean.hobby}" required="true" />
                    </f:facet>
                </h:column>
                <h:column>
                    <h:outputText value="#{h.like}" />
                    <f:facet name="footer">
                        <h:inputText value="#{outerBean.like}" required="true" />
                        <h:commandButton action="#{outerBean.addHobby}" value="+" immediate="true">
                            <f:ajax render="ht" />
                        </h:commandButton>
                    </f:facet>
                </h:column>
            </h:dataTable>
        </h:panelGrid>
        </h:form>
    </h:body>
    </html>

是的,外部表单没有命令按钮,但这不是问题。 commandButton用于内部表单,因此设置属性immediate = true。执行此操作时,不会检查所有字段是否为空(必需 - 标记被忽略)。但也是这些字段的内容被忽略而未设置为ajax请求。如何避免这种情况并将ajax请求中的h.hobby和h.like的字段值发送到OuterBean?

这里的豆子:

    @ManagedBean
    @SessionScoped
    public class OuterBean
    {
        private List<HobbyBean> hobbies;
        private String name;
        private String hobby;
        private Integer like;

        public OuterBean()
        {
            hobbies = new ArrayList<HobbyBean>();
        }

        public String addHobby()
        {
            hobbies.add(new HobbyBean(hobby, like));
            System.out.println("hobbies: " + hobbies.toString());
            return "";
        }

        public String submit()
        {
            System.out.println("name is " + name);
            return "";
        }
    // + getter & setter
    }

    /* ------------------------------------------------------------------------ */

    public class HobbyBean
    {
        private String hobby;
        private Integer like;

        public HobbyBean(String hobby, Integer like)
        {
            this.hobby = hobby;
            this.like = like;
        }

        public String toString()
        {
            return hobby == null ? "" : hobby.concat(",").concat(like == null ? "" : like.toString());
        }
    // + getter & setter
    }

现在当我向bean添加一个爱好时发生的事情是没有添加任何爱好,因为bean字段的爱好和喜欢没有设置(列表为空,log为:“hobbies:[]”)。我怎样才能使它发挥作用?

1 个答案:

答案 0 :(得分:1)

你的爱好是空的,因为你没有告诉f:ajax提交什么。如果你想进行部分提交(我想这就是你想要的)你可以尝试以下方法:

<h:form>
    <h:panelGrid columns="2">
        <h:outputText value="Name" />
        <h:inputText value="#{outerBean.name}" required="true" />
        <h:outputText value="Hobbies" />
        <h:dataTable id="ht" value="#{outerBean.hobbies}" var="h">
            <h:column>
                <h:outputText value="#{h.hobby}" />
                <f:facet name="footer">
                    <h:inputText id="hobby" value="#{outerBean.hobby}" required="true" />
                </f:facet>
            </h:column>
            <h:column>
                <h:outputText value="#{h.like}" />
                <f:facet name="footer">
                    <h:inputText id="like" value="#{outerBean.like}" required="true" />
                    <h:commandButton action="#{outerBean.addHobby()}" value="+" >
                        <f:ajax execute="hobby like" render="ht" />
                    </h:commandButton>
                </f:facet>
            </h:column>
        </h:dataTable>
    </h:panelGrid>
</h:form>

正如您在代码中看到的那样:f:ajax当您按下按钮时,需要提交表单的一部分。如果你现在检查你的bean,你会看到只有爱好和类似的东西被添加到bean中。名称部分将不会被提交。你说没有检查所有字段。这是因为你使用immediate = true这会跳过验证。我建议不要使用它。在这里查看有关immediate = true的更多信息http://balusc.blogspot.nl/2006/09/debug-jsf-lifecycle.html#WhenShouldIUseTheImmediateAttribute希望这对您有所帮助。