JSF不工作:选择SelectOneMenu并使用Ajax动态更新其他SelectOneMenu

时间:2014-11-21 15:12:24

标签: java html ajax jsf

我一直试图找出问题很长一段时间,对我来说没有成功的结果。我在谷歌搜索这个,我尝试了几个不同的工作示例,但没有人帮助我解决我的任务。

问题是当“类别”selectOneMenu被更改时,“Messages”selectOneMenu不会更新。它不会加载所选类别的消息。

在HTML中,我只有两个selectOneMenu元素。在服务类中,我制作用户,类别和消息,并将它们添加到链接列表中。

HTML

    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core" 
      xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    </h:head>

    <h:body>
        <h:form>
            <h:outputText value="You have no categories made yet..." rendered="#{empty categoryBean.categories}" />
            <h:selectOneMenu value="#{categoryBean.category}" rendered="#{not empty categoryBean.categories}">
                <f:selectItems value="#{categoryBean.categories}" />
                <f:ajax event="change" render="messages" listener="#{categoryBean.changeCategory}" />
            </h:selectOneMenu>

            <h:outputText value="This category has no messages yet..." rendered="#{empty categoryBean.messages}" />
            <h:selectOneMenu value="#{categoryBean.message}" id="messages" rendered="#{not empty categoryBean.messages}">
                <f:selectItems value="#{categoryBean.messages}" />
            </h:selectOneMenu>
        </h:form>
    </h:body>
</html>

豆:

    package beans;

    @Named(value = "categoryBean")
    @SessionScoped
    public class CategoryBean implements Serializable {
        private List<Message> messages;
        private Category category;
        private Message message;

        @Inject
        private Service service;
        /**
         * Creates a new instance of CategoryBean
         */
        public CategoryBean() {
            category = new Category();
        }

        public void setCategory(Category category) {
            this.category = category;
        }

        public Category getCategory(){
            return this.category;
        }

        public List<Category> getCategories() {
            return service.getCategories();
        }

        public List<Message> getMessages() {
            return this.category.getMessageList();
        }

        public Message getMessage() {
            return message;
        }

        public void setMessage(Message message) {
            this.message = message;
        }

        public void changeCategory() {
            this.messages = category.getMessageList();
        }
    }

服务

package service;

@Named(value = "service")
@ApplicationScoped
public class Service {
    private final ArrayList<User> users = new ArrayList<>();

    public Service() {
        User u1 = new User("Mikolaj", "Stasinski", "mikolaj", "123456", 2);
        User u2 = new User("Toms", "Bugna", "toms", "789012", 2);
        User u3 = new User("Algie", "Tiempo", "algiemay", "123456", 1);

        users.add(u1);
        users.add(u2);
        users.add(u3);

        Category c1 = new Category(u1, "SADP", "Advanced Java");
        Category c2 = new Category(u1, "SADP Kaj", "JSF");
        Category c3 = new Category(u2, "CNDS", "Networking");

        u1.addCategory(c1);
        u1.addCategory(c2);
        u2.addCategory(c3);

        Message m1 = new Message(u3, c3, "This is a message.");
        Message m2 = new Message(u3, c1, "Another Message1");
        Message m3 = new Message(u3, c1, "Another Message2");

        u3.addMessage(m1);
        u3.addMessage(m2);
        u3.addMessage(m3);

        c1.addMessage(m2);
        c1.addMessage(m3);
        c3.addMessage(m1);
        c2.addMessage(m3);
    }

    public List<User> getUsers(){
        return new ArrayList<>(users);
    }

    public List<Category> getCategories(){
        ArrayList<Category> categoryList = new ArrayList<>();

        for (User u: users) {
            for (Category cat: u.getCategoryList()) {
                categoryList.add(cat);
            }
        }

        return categoryList;
    }
}

2 个答案:

答案 0 :(得分:1)

可能是因为您的侦听器方法的签名不正确,它应该如下所示:

public void changeCategory(AjaxBehaviorEvent event) {     
   this.messages = category.getMessageList();   
}    

查看此帖The f:ajax listener method in h:selectOneMenu is not executed并按照工作示例进行操作。

答案 1 :(得分:1)

问题是渲染条件与id位于同一位置。如果某个组件未呈现,则无法找到其ID。然后,第一个选择不能正确刷新第二个选择。将具有呈现条件的组件插入到具有用于刷新的id的容器中:

<h:form>
    <h:outputText 
        value="You have no categories made yet..." 
        rendered="#{empty categoryBean.categories}" />

    <h:selectOneMenu 
        value="#{categoryBean.category}" 
        rendered="#{not empty categoryBean.categories}">
        <f:selectItems value="#{categoryBean.categories}" />
        <f:ajax event="change" 
            render="messages" 
            listener="#{categoryBean.changeCategory}" />
    </h:selectOneMenu>

    <h:panelGroup id="messages">
        <h:outputText 
            value="This category has no messages yet..." 
            rendered="#{empty categoryBean.messages}" />
        <h:selectOneMenu 
            value="#{categoryBean.message}" 
            rendered="#{not empty categoryBean.messages}">
            <f:selectItems value="#{categoryBean.messages}" />
        </h:selectOneMenu>
    </h:panelGroup>

</h:form>

更新:第二个问题是您选择管理对象。在内部,selectOneMenu使用字符串来管理值,使用您需要实现的对象并为每种类型使用Converter。在此Converter类中,您需要将对象转换为String,并将此String再次转换为同一对象。您可以在此处查看更多信息: How create a custom coverter in JSF 2?