f: ValueChangeListener аннулирует EJB-инъекцию - PullRequest
1 голос
/ 07 июля 2011

Он прекрасно загружает stateList, но когда я изменяю значение состояния, он вызывает бэк, но addressBO имеет значение null. Как я могу это исправить? Есть ли другой способ сделать это?

Заранее спасибо.

<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>

BackBean

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);
 }

}

Другой бэк, который устанавливает значение адреса и пользователя, который не появляется в этом случае.

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;
 }

}

1 Ответ

1 голос
/ 07 июля 2011

Первая проблема заключается в том, что вы создаете новый экземпляр класса в теге <f:valueChangeListener>. Это не тот же экземпляр, на который ссылается @ManagedBean, и аннотации к управляемым компонентам также не будут вызываться для этого. Вместо этого вы бы хотели использовать valueChangeListener="#{addressController.processValueChange}" на <h:selectOneMenu>. Но это не сразу решает все. Большое изменение: второй список ведет себя не так, как ожидалось.

Вторая проблема заключается в том, что метод слушателя изменения значения вызывается во время фазы Validations . Это неподходящий момент для изменения / загрузки значений модели. Вы должны сделать это во время фазы Invoke Action . Используйте атрибут 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);
    }

    // ... 
}
...