【问题标题】:JSF Not Working: Select SelectOneMenu And Dynamically Update Other SelectOneMenu With AjaxJSF 不工作:选择 SelectOneMenu 并使用 Ajax 动态更新其他 SelectOneMenu
【发布时间】:2015-01-19 18:45:13
【问题描述】:

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

问题是当“类别”selectOneMenu 更改时,“消息”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;
    }
}

【问题讨论】:

    标签: java html ajax jsf


    【解决方案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 类中,您需要将您的对象转换为字符串,并将此字符串再次转换为同一对象。您可以在此处查看更多信息: How create a custom coverter in JSF 2?

    【讨论】:

    • 它标记已经找到一个“消息”ID的错误。这是因为 panelGroup 的 ID 为“Messages”,而 selectOneMenu 的 ID 为“Messages”。我应该将哪个更改为其他 id 名称?
    • 抱歉,我忘记从 selectOneMenu 中删除消息 ID。我升级了答案。
    • 还是不行。正如我之前在回答用户 Mooolo 时所说,我认为在第一个 SelectOneMenu 更改过程中,“categoryBean.category”变量不会更改为选定的类别/项目。
    • 再次抱歉,我还没有看到第二个问题,我用选择的字符串而不是对象进行了测试:P。答案已更新
    • 我明白你建议我做什么以及为什么要这样做,但我担心我将无法生成这个转换器的代码:/ 我只是试着去做,但它并没有真正做到工作..
    【解决方案2】:

    可能是因为你的监听方法的签名不正确,应该是这样的:

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

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

    【讨论】:

    • 我已经试过了,只是再试了一次。没有。这是行不通的。仍然没有更改第二个 SelectOneMenu。有什么想法吗?
    • 问题是在第一次 SelectOneMenu 更改 categoryBean.category 变量不会更改为所选类别。我该如何解决这个问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 2014-11-20
    • 2012-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多