2012-02-03 102 views
0

我有一个行为,我不明白与selectonemenu。我会试着解释它是否有人知道发生了什么。我正在用glassfish3使用JSF2。 我的XHTML代码如下:JSF生命周期 - selectonemenu

<h:selectOneMenu binding="#{cetBacking1.menuFamilies}" 
        valueChangeListener="#{cetBacking1.listenerFamilia}" 
        onchange="this.form.submit()"> 
    <f:selectItems value="#{cetBacking1.ompleFamiliesTemplate()}"></f:selectItems> 
</h:selectOneMenu> 
<h:commandButton value="Test" type="submit" action="#{cetBacking1.test()}"> </h:commandButton> 

我用绑定,因为这取决于selectOneMenu用于值我将呈现一些其他的成分,但现在这是超出范围。命令按钮用于提交。 ompleFamiliesTemplate()返回选择项列表。 和背bean是:

@ManagedBean(name="cetBacking1") 
@SessionScoped 
public class cetBacking1 extends AbstractEntityAccessor implements Serializable { 
private List<SelectItem> llistaFamilies = new ArrayList<SelectItem>(); 
private HtmlSelectOneMenu menuFamilies; 
{ 
    System.out.println("cetBacking1.init"); 
    ompleFamiliesTemplate(); 
} 


public void listenerFamilia(ValueChangeEvent event) { 
    String novaFamilia = (String) event.getNewValue(); 
    System.out.println("cetBacking1.listenerFamilia: " + novaFamilia); 
} 

public List ompleFamiliesTemplate() { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    List<FamiliaTemplate> llistaFamiliestmp = new ArrayList<FamiliaTemplate>(); 
    System.out.println("cetBacking1.ompleFamiliesTemplate !!!!!!"); 
    if (context.getExternalContext().getSessionMap().containsKey("LlistaFamilies")) { 
     llistaFamiliestmp = (List<FamiliaTemplate>) context.getExternalContext().getSessionMap().get("LlistaFamilies"); 
     if (llistaFamilies.isEmpty()) { 
      for (Iterator it = llistaFamiliestmp.iterator(); it.hasNext();) { 
       FamiliaTemplate object = (FamiliaTemplate) it.next(); 
       llistaFamilies.add(new SelectItem(String.valueOf(object.getIdfamiliaTemplate()), object.getFamilia())); 
      } 
     } 
    } 
    return llistaFamilies; 
} 
public void submit() { 
    System.out.println("cetBacking1.submit !!"); 
} 

我把一些的System.out.println按照功能的不同来电,cetBacking1豆构造和ompleFamiliesTemplate(),和valueChangeListener。 该页面第一次在服务器日志加载出现下一个消息:

INFO: cetBacking1.init 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 

的{} bean的函数被调用,它调用cetBacking1.ompleFamiliesTemplate和第二cetBacking1.ompleFamiliesTemplate是由F称为:selectItems的。它按预期工作。现在我改变selectOneMenu用于临屋区的价值和在日志中出现:

INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 

到cetBacking1.ompleFamiliesTemplate的最后一个电话我认为,由f称为:selectItems的。但我不是为什么在开始时调用cetBacking1.ompleFamiliesTemplate两次,然后调用cetBacking1.listenerFamilia两次。 但是下一个对我来说更加惊人。我再次更改selectOneMenu并在日志中显示: 信息:cetBacking1.ompleFamiliesTemplate !!!!!! 信息:cetBacking1.ompleFamiliesTemplate !!!!!! INFO:cetBacking1.listenerFamilia:3 INFO:cetBacking1.listenerFamilia:3 INFO:cetBacking1.listenerFamilia:3 INFO:cetBacking1.ompleFamiliesTemplate !!!!!!

cetBacking1.ompleFamiliesTemplate与前面一样在开始时被调用两次,但是侦听器被调用了三次。每次我改变selectOneMenu时,都会再次调用监听器。如果我改变了selectOneMenu用于值两倍的日志如下:

INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.listenerFamilia: 1 
INFO: cetBacking1.listenerFamilia: 1 
INFO: cetBacking1.listenerFamilia: 1 
INFO: cetBacking1.listenerFamilia: 1 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.listenerFamilia: 2 
INFO: cetBacking1.ompleFamiliesTemplate !!!!!! 

的问题是,为什么cetBacking1.ompleFamiliesTemplate被称为两次当我改变selectOneMenu用于值,听者执行之前。以及为什么第一次更改selectOneMenu值时侦听器执行了两次,并且每次更改该值时又多一次。

在此先感谢

+0

正如耶利米回答的那样,你的具体问题是你在getter方法中做了业务逻辑。这是错误的。只是一个建议,如果你使用JSF 2.x,不要过分关注JSF 1.x目标书籍/资源。无论你想要达到什么,都可以通过''来完成。 – BalusC 2012-02-03 19:07:51

回答

0

一个月前我有同样的问题。 解决方法是,SessionScope和绑定不兼容。

你必须删除你的jsf页面的绑定,一切工作正常。 要填充SelectCombo,您可以使用List<SelectItem>和项目。