CDI事件不适用于com.vaadin.cdi.ViewScoped

时间:2018-06-09 11:52:35

标签: vaadin cdi vaadin8

我目前正在玩Vaadin 8.4.2 + CDI。

我得到了一个简单的视图,其中包含一个简单的模型类Person,它具有2个属性(lastnamefirstname)。我有一个简单的视图(GreetPersonView)和一个@ViewScoped组件(MessageDisplay),它被注入到视图中。按下按钮时,会触发一个事件,MessageDisplay类会观察此事件,当事件被触发时,它将显示一条简单的消息(请参阅下面的代码)。现在,当MessageDisplay是ViewScoped时,Observer不会被触发。当我将其更改为UIScoped时,它可以正常工作。这是有意的吗? Vaadin中有这个Bug吗?

@CDIView(GreetPersonView.VIEWNAME)
public class GreetPersonView extends CustomComponent implements View {
public final static String VIEWNAME = "greetperson";


private Person person;

@Inject
private javax.enterprise.event.Event<String> messageEvent;

@Inject
private MessageDisplay messageDisplay;

@Override
public void enter(ViewChangeListener.ViewChangeEvent event) {
    person = new Person();

    VerticalLayout layout = new VerticalLayout();

    Binder<Person> binder = new Binder<>();
    person.setFirstName("John");
    person.setLastName("Doe");

    // An input field for editing injected data
    TextField firstName = new TextField("First name");
    layout.addComponent(firstName);
    TextField lastName = new TextField("Last name");
    layout.addComponent(lastName);

    binder.bind(firstName,
            Person::getFirstName,
            Person::setFirstName);
    binder.bind(lastName,
            Person::getLastName,
            Person::setLastName);

    binder.readBean(person);

    Button helloButton = new Button("Say Hello");
    layout.addComponent(helloButton);
    helloButton.addClickListener(e -> {
        try {
            binder.writeBean(person);
            messageEvent.fire(person.getFirstName() + " " + person.getLastName());
        } catch (ValidationException e1) {
            Notification.show("Person could not be saved, " +
                    "please check error messages for each field.");
        }
    });

    layout.addComponents(messageDisplay);

    setCompositionRoot(layout);

}
}


@ViewScoped
public class MessageDisplay extends Panel {
    private Label lblMessage;

    public MessageDisplay() {
        lblMessage = new Label("Nothing to show");
        setContent(lblMessage);
    }

    public void onMessageReceived(@Observes String message) {
        this.lblMessage.setValue("Hello " + message);
    }
}

1 个答案:

答案 0 :(得分:-1)

CDI活动是POJO。所以首先你应该创建像MessageEvent这样的自定义事件,我假设您希望将String消息作为数据,并分别使用getMessage()和setMessage()方法以及带有String参数的构造函数。

然后做

@Inject
private javax.enterprise.event.Event<MessageEvent> messageEvent;
...
messageEvent.fire(new MessageEvent(person.getFirstName() + " " + person.getLastName()));
...

观察它

public void onMessageReceived(@Observes MessageEvent messageEvent) {
     this.lblMessage.setValue("Hello " + messageEvent.getMessage());
}