1

它可以很好地加载 stateList,但是当我更改状态的值时,它会调用 backbean 但 addressBO 为空。我该如何解决?还有其他方法吗?

提前致谢。

<h:selectOneMenu id="stateList" value="#{newUserController.address.stateID}">
 <f:selectItems value="#{addressController.stateList}" />
 <f:valueChangeListener type="controller.address.AddressController"/>
 <f:ajax event="change" render="cidadeList"/>
</h:selectOneMenu>

<h:selectOneMenu id="cityList" value="#{newUserController.address.cityID}">
 <f:selectItems value="#{addressController.cityList}" />
</h:selectOneMenu>

背豆

package controller.address;

@ManagedBean
@RequestScoped
public class AddressController implements ValueChangeListener {

 @EJB
 private AddressBO addressBO;

 @PostConstruct
 public void firstThingToDo() {
  stateList = enderecoBO.loadStateListSelectItem();
 }

 @Override
 public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
  String state = (String) event.getNewValue();
  cityList = addressBO.loadCityList(state);
 }

}

设置的另一个 backbean 是在这种情况下未出现的地址和用户的值。

package controller.user;

@ManagedBean
@RequestScoped
public class NewUserController {

 private Address address;
 private User user;

 @EJB
 private NewUserBO newUserBO;

 public void registerNewUser() {
  newUserBO.register(user, address);
 }

 public Address getAddress() {
  return this.address;
 }

 public void setAddress(Address address) {
  this.address = address;
 }

 public User getUser() {
  return this.user;
 }

 public void setUser(User user) {
  this.user = user;
 }

}
4

1 回答 1

1

<f:valueChangeListener>第一个问题是您正在标签中创建一个全新的类实例。这引用的实例不同,@ManagedBean并且托管 bean 相关的注释也不会被调用。你宁愿用valueChangeListener="#{addressController.processValueChange}"on<h:selectOneMenu>代替。但这并不能立即解决所有问题。变化很大,第二个列表的行为不如预期。

第二个问题是在验证阶段调用了值更改侦听器方法。这是更改/加载模型值的错误时机。您应该在调用操作阶段执行此操作。使用 的listener属性<f:ajax>

所以:

<h:selectOneMenu id="stateList" value="#{newUserController.address.stateID}">
    <f:selectItems value="#{addressController.stateList}" />
    <f:ajax listener="#{addressController.changeState}" render="cidadeList" />
</h:selectOneMenu>

@ManagedBean
@RequestScoped
public class AddressController {

    @EJB
    private AddressBO addressBO;

    @PostConstruct
    public void init() {
        stateList = enderecoBO.loadStateListSelectItem();
    }

    public void changeState(AjaxBehaviorEvent event) {
        String state = (String) ((UIInput) event.getComponent()).getValue();
        cityList = addressBO.loadCityList(state);
    }

    // ... 
}
于 2011-07-07T19:53:17.080 回答