如何使用Vaadin CDI和Navigator实施MVP? [英] How to implement MVP using Vaadin CDI and Navigator?

查看:115
本文介绍了如何使用Vaadin CDI和Navigator实施MVP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I would like to implement the MVP pattern in my web application using Vaadin. I am using the Vaadin Navigator and the CDIViewProvider, something like so:

//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 {
    // ...

据我所知,视图提供程序实例化了一个MyViewImpl对象(即ViewScoped),即,当用户导航到该视图/从该视图中移出时,该对象被创建/销毁.接下来,我需要考虑在哪里实例化此视图的演示者.我考虑过将其设为SessionScoped并将其注入视图:

To my understanding the view provider instantiates an object of MyViewImpl which is ViewScoped, i.e. it gets created/destroyed as the user navigates to/out of this view. Next I need to think about where to instantiate the presenter of this view. I thought about making it SessionScoped and inject it to the view:

// ... 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();
}

正如我已经在演示者引用该视图后面的注释中指出的那样,我不知道演示者如何获得该视图实例的持有权(该实例由视图提供者创建).当视图改变时,只要创建/销毁视图,让演示者使用SessionScope甚至有意义吗?一种替代方式是该视图没有对演示者的引用,但是演示者将自己添加为该视图的侦听器.但是,在这种情况下,我再次不知道在哪里实例化演示者以及如何获取对当前视图的引用.

As I already pointed out in the comment behind the presenters reference to the view I do not know how the presenter can get a hold of the view instance (which is created by the view provider). Does it even make sense to have the presenter be SessionScoped, while the views get created/destroyed whenever the view changes ? An alternative way would be that the view does not have a reference to the presenter, but that the presenter adds itself as the listener to the view. However in this case I again do not know where to instantiate the presenter and how to get a reference to the current view.

推荐答案

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

Don't try to inject the view, use a view setter in presenter instead and call it from view's @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创建. Presenter由CDI的视图实例化(即使它监督该视图),并且应该具有@Dependent范围.

I think that creation order is the confusing issue here. In a way views have higher priority as they are created by Vaadin when you call getNavigator().navigateTo("my-view"). Presenter is instantiated by the view by CDI (even though it supervises the view) and should have @Dependent scope.

这篇关于如何使用Vaadin CDI和Navigator实施MVP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆