如何使用Vaadin CDI和Navigator实现MVP?

时间:2015-08-24 14:08:54

标签: java vaadin cdi mvp

我想使用Vaadin在我的Web应用程序中实现MVP模式。我正在使用Vaadin Navigator和CDIViewProvider,如下所示:

//MyUI.java
public class MyUI extends UI {
    @Inject
    CDIViewProvider viewProvider;

    Navigator navigator;

    @Override
    protected void init(VaadinRequest vaadinRequest) {

        //UI setup
        navigator = new Navigator(this, someContainer);
        navigator.addProvider(viewProvider);
        getNavigator().navigateTo("myView");
    }
}

//MyViewImpl.java
@CDIView("myView")
public class MyViewImpl extends VerticalLayout implements com.vaadin.navigator.View, MyView {
    // ...

据我所知,视图提供程序实例化了ViewView的MyViewImpl对象,即当用户导航到/退出此视图时,它会被创建/销毁。接下来我需要考虑在哪里实例化此视图的演示者。我想过让它成为SessionScoped并将其注入视图:

// ... continue MyViewImpl.java

@Inject 
private MyViewListener presenter;

// in some of the MyViewImpl methods we can do stuff like presenter.buttonClicked();
}

//MyViewPresenter.java
@SessionScoped
public class MyViewPresenter implements MyView.MyViewListener {

    MyView view; //how can the presenter obtain the view here ?

    @PostConstruct
    public void init() 
    @Override
    public void buttonClicked() {
        view.displaySomething();
    }
}

//MyView.java
public interface MyView {
    public interface MyViewListener {     
        public void buttonClicked();
    }

    public void displaySomething();
}

正如我在演示者背后的评论中已经指出的那样,我不知道演示者如何获取视图实例(由视图提供者创建)。让演示者成为SessionScoped甚至是有意义的,而只要视图发生变化,视图就会被创建/销毁吗?另一种方法是视图没有对演示者的引用,但是演示者将自己添加为视图的侦听器。但是在这种情况下,我再次不知道在何处实例化演示者以及如何获取对当前视图的引用。

2 个答案:

答案 0 :(得分:1)

不要尝试注入视图,而是在演示者中使用视图设置器,并从视图@PostConstruct中调用它:

@Dependent
class MyPresenter {

    private MyView view;

    public void setView(MyView view) {
        this.view = view;
    }
}

public interface MyView {
}

@CDIView("my-view")
public class MyViewImpl extends VerticalLayout implements View, MyView {

    @Inject
    private MyPresenter presenter;

    @PostConstruct
    private void init() {
        presenter.setView(this);
    }
}

我认为创作顺序是一个令人困惑的问题。在某种程度上,视图具有更高的优先级,因为当您调用getNavigator().navigateTo("my-view")时,Vaadin会创建它们。 CDI通过视图实例化Presenter(即使它监视视图)并且应该具有@Dependent范围。

答案 1 :(得分:0)

我认为重点是视图会引导演示者,反之亦然。因此,您采用上述方法的一种策略是在视图中Presenter @Dependent确定范围,并@Inject MyViewPresenter presenter @Inject { {1}} MyView进入演示者。 view使它们位于相同的范围内,这很可能是你想要实现的目标