GWT MVP UiBinder - 将参数传递给演示者

hba*_*hba 2 mvp gwt uibinder

我已经开始了一个GWT项目,我决定试试UiBinder.我很难在UiBinder上面放置一个MVP模式.

当我使用GWT-pure-java时:我会使用Gin为我的演示者注入相应的视图.这是非常直接的,如果我想将一个id传递给演示者,那么我只需将一个id传递给演示者的构造函数.

与UiBinder不太直接.我几乎可以肯定我错过了一些东西,因为很多人都声称UiBinder和MVP是在天堂做的比赛......所以我希望能在这个问题上得到一些坚实的回答;-)

我在几个简单的GWT-UiBinder示例中看到的是,视图是由绑定器创建的,然后是:

  1. 视图在其构造函数中或通过@UIFactory方法构造演示者.
  2. 相应的演示者被传递给视图(通过一个setter,不用说在构建视图之后).

使用第一种方法,如果在视图中构建演示者,如何将id传递给演示者?你会这样做view.getPresenter().setId(42);,然后主持人会去服务器获取一些信息,并要求视图显示它......闻起来很糟糕.

使用第二种方法,最终会得到一个非直观的对象图,其中不清楚谁是消费者,谁是生产者.此外,在视图需要来自演示者的信息(几乎所有用例都需要此信息)的情况下,人们会做什么:

//some code would create the presenter pass it the id and then call view.setPresenter
class MyView {
    void setPresenter(MyPresenter p) {
    this.presenter = p;
    //OK now that i have my presenter how do I ask it to fetch data from the server.
    //do i turn around and do: presenter.setView(this); and then the presenter takes 
    //over and uses the view to display the data?
     }
 }
Run Code Online (Sandbox Code Playgroud)

这同样很臭......很抱歉这篇长篇文章,并提前感谢...

fil*_*fku 6

你是对的,将一个View引用它的Presenter看起来似乎有点不洁净,并让主持人引用View.

我看到它的方式,以及谷歌开发页面在MVP上的概述有两种风格的MVP:

  1. 有一个不了解其演示者的视图,并用演示者"包装"它.该视图为演示者提供了足够的API来获取/设置它关心的所有数据.此外,演示者必须知道视图可以生成的所有事件类型,以响应用户交互.这是MPV第1部分的方法.
  2. 演示者再次了解视图,但这次只能获取/设置数据容量.演示者不关心视图中的UI事件.相反,演示者为视图提供API,以便在事件以我们的演示者中的"onSomethingHappened()"方式发生时调用/通知它.这允许我们捕获演示者本身中的所有行为/逻辑,并在视图中发生某些事情时根据需要调用它.然后,视图可以以任何合适的方式处理非常低级别的事件 - 无论是使用GWT事件/窗口小部件还是使用元素/ HTML的原始DOM事件(UiBinder/GWT性能最佳实践).这是MVP第2部分的方法.

我更喜欢选项2,因为它允许演示者完全专注于必要的行为.该视图可以根据需要处理小部件/ html /事件处理,并将其简化为调用演示者的"onSomething()"调用.这些小部件/事件实现可能是简单或复杂的优化事件.演示者不受细节影响(并且未受污染),因为它只是得到通知.我觉得这个选项更清晰地分离了表现和行为.请注意,它也是Observer Pattern的1对1实现,因此View和Presenter之间的互连是必要的.

至于创作,我觉得Presenter是一个更强大的实体,尽管它扮演观察者的角色.我会创建必要的演示者,然后传递它关注的视图.然后,演示者可以控制视图,并将视图传递给自我引用.

至于你的制作人/消费者比喻,我认为主持人是消费者.视图生成UI事件(用户交互),演示者通过提供必要的行为进行响应.这应该是视图和演示者之间唯一的联系点 - 视图调用类似"onSomethingHappened()"的方法,并且演示者完成工作.该视图永远不会告诉演示者"fetchData()"或类似的东西.

我最近刚开始使用UiBinder + MVP,所以这就是我的想法.我希望它有所帮助!