2014-11-21 109 views
0

我一直在试图找出问题很长时间,没有成功的结果。我在谷歌搜索这个,我尝试了几个不同的工作例子,但没有人帮助我解决我的任务。JSF不工作:选择SelectOneMenu并动态更新其他SelectOneMenu With Ajax

问题是,当“类别”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; 
    } 
} 

回答

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类中,您需要将字符串中的对象转换为同一对象中的此字符串。你可以在这里看到更多的信息: How create a custom coverter in JSF 2?

+0

它标记已经找到一个“消息”ID的错误。这是因为panelGroup的id为“Messages”,selectOneMenu的id为“Messages”。我应该更改哪一个其他id名称? – 2014-11-21 19:55:33

+0

对不起,我忘了从selectOneMenu中删除消息ID。我升级了答案。 – Corus 2014-11-21 19:57:05

+0

仍然无效。正如我之前在回答用户Mooolo时所说的那样,我认为在第一个SelectOneMenu更改过程中,“categoryBean.category”变量不会更改为选定的类别/项目。 – 2014-11-21 20:02:44

1

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

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

看一看这篇文章The f:ajax listener method in h:selectOneMenu is not executed,并按照工作实例。

+0

我试过这个,只是再试一次。不。这是行不通的。仍然没有改变第二个SelectOneMenu。有任何想法吗? – 2014-11-21 18:09:09

+0

问题是,首先SelectOneMenu更改categoryBean.category变量不会更改为选定的类别。我如何解决这个问题? – 2014-11-21 18:26:50