GWT MVP UiBinder - 将参数传递给演示者
我已经开始了一个 GWT 项目,我决定尝试一下 UiBinder。我很难在 UiBinder 之上建立 MVP 模式。
当我使用 GWT-pure-java 时:我会使用 Gin 向我的演示者注入相应的视图。这非常简单,如果我想将 id 传递给演示者,那么我只需将 id 传递给演示者的构造函数即可。
UiBinder 就不那么简单了。我几乎可以肯定我错过了一些东西,因为很多人都声称 UiBinder 和 MVP 是天作之合......所以我希望在这个问题上得到一些可靠的答复;-)
我是什么我们在几个简单的 GWT-UiBinder 示例中看到的是,视图是由绑定器创建的,然后:
- 视图在其构造函数中或通过 @UIFactory 方法构造呈现器。
- 相应的presenter被传递给view(通过setter,不用说是在view构造之后)。
使用第一种方法,如果在视图中构造演示者,如何将 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?
}
}
这同样很臭……抱歉,帖子很长,提前感谢……
I've started a GWT project, I've decided to give the UiBinder a try. I'm having a difficult time laying an MVP pattern on top of UiBinder.
When I was using GWT-pure-java: I'd use Gin to inject my presenter with the corresponding view. It was pretty straight forward, and if I wanted to pass an id into the presenter, then I would simply pass an id into the presenter's constructor.
Not so straight forward with UiBinder. I'm almost certain that I'm missing something, because lots of people are claiming that UiBinder and MVP are a match made in heaven...so I'm hoping to get some solid responses on this query ;-)
What I've seen in several trivial GWT-UiBinder examples, is that the view is created by the binder then either:
- The view constructs the presenter either in its constructor or via a
@UIFactory
method. - The corresponding presenter is passed to the view (via a setter, needless to say after the view is constructed).
With the first approach, how does one pass an id to the presenter if the presenter is being constructed in the view? Would you do view.getPresenter().setId(42);
, and then the presenter would go to the server get some info and ask the view to display it...smells bad.
With the second approach, one would end up with a non-intuitive object graph in which it is not clear who is the consumer and who is the producer. Also, in situations where the view requires information from the presenter (almost all use-cases require this) what would one do:
//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?
}
}
This is equally smelly...Sorry for the long post, and thanks in advance...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你是对的,让视图引用其演示者,并让演示者引用视图确实看起来有点不干净。
在我看来,以及 MVP 上的 google 开发页面如何概述 MVP 有两种风格:
我更喜欢选项 2,因为它允许演示者完全专注于必要的行为。视图可以根据需要处理小部件/html/事件处理,并将其简化为对演示者的“onSomething()”调用。这些小部件/事件实现可能是简单的或复杂的和优化的事件。演示者不会受到细节的影响(也不会受到污染),因为它只是收到通知。我觉得这个选项可以更清晰地分离表现和行为。请注意,它也是 观察者模式 的 1 对 1 实现,因此 View 和 View 之间的互连主持人是必要的。
至于创作,我觉得演示者是更强的实体,尽管它扮演的是观察者的角色。我将创建必要的演示者,然后将关注的视图传递给它。然后演示者可以控制视图,并向视图传递自引用。
至于你的生产者/消费者的类比,我认为演示者就是消费者。视图生成 UI 事件(用户交互),演示者通过提供必要的行为进行响应。这应该是视图和演示者之间的唯一联系点 - 视图调用“onSomethingHappened()”等方法,然后演示者完成工作。视图永远不会告诉演示者“fetchData()”或类似的内容。
我自己最近才开始使用UiBinder + MVP,所以这只是我的想法。我希望它有帮助!
You're right in that it does seem a bit unclean to have both a View reference its Presenter, and have the presenter reference the View.
The way I see it, and how the google dev pages on MVP outline there are two flavours of MVP:
I prefer option 2 as it allows the presenter to be purely focused on the necessary behaviour. The view can deal with widgets/html/event handling as necessary and simplify it to calls to "onSomething()" calls for the presenter. Those widget/event implementations might be simple or complex and optimized events. The presenter is unaffected (and unpolluted) by the detail, as it just gets notified. I feel this option is a cleaner separation of presentation and behaviour. Note it's also a 1 to 1 implementation of the Observer Pattern, so the interconnection between View and Presenter is necessary.
As for creation, I feel the Presenter is the stronger entity despite it playing the Observer role. I would create the necessary presenter and then pass it the view of concern. The presenter can then take control of the view, and pass the view a self reference.
As for your producer/consumer analogy I think the presenter is the consumer. The view produces UI events (user interaction) and the presenter responds by providing the necessary behaviour. That should be the only point of contact between the view and presenter - the view calls methods like "onSomethingHappened()" and the presenter does the work. The view would never tell the presenter "fetchData()" or anything like that.
I've just started using UiBinder + MVP recently myself, so this is just what I think. I hope it helps!
自从我开始这个帖子并阅读回复以来已经过去了几天。我已经决定了我的方法。我以为我只是在这里提到它。
再次感谢您的深思熟虑的回复……他们很有帮助。
由于 filip-fku 指出演示者是主要实体,因此我决定在我的 mvp 对象的生命周期管理期间继续威胁他们。换句话说,视图不会实例化演示者。演示者由其他演示者实例化(在某些时候我将委托给 Gin)。
演示者的构建器可以访问其相应的视图,并将视图注入演示者(通过构造函数)。
视图本身要么由构建器实例化,要么由 UiBinder 实例化为更大视图的一部分。在后一种情况下,UiBinder 实例化视图,父视图有一个 getter。下面是这种情况的一个示例:
然后在 FormPresenter 中我这样做:
我基本上保持了与纯 java 方法类似的 mvp 生命周期。一旦我从中获得一些里程,我将用 Gin 重构它。
再次感谢。
PS,如果您还没有看过上面提到的 I/O 演示,那么值得一看。
It has been a few days since I started this thread and read the responses. I've decided on my approach. And I'd thought I just mention it here.
Once again, thanks for the thoughtful responses...they were helpful.
As filip-fku pointed out presenters are the main entity, so I decided to continue to threat them as such during the life-cycle management of my mvp objects. In other words, the views do not instantiate the presenters. The presenters are instantiated by other presenters (at some point i'll delegate to Gin).
The
builder
of a presenter has access to its corresponding view, and injects the presenter (via constructor) with the view.The views themselves are either instantiated by the
builder
or instantiated by UiBinder as part of a larger view. In the latter case where UiBinder instantiates the view the parent view has a getter. Here is an example of this case:Then in the FormPresenter I do:
I have essentially kept the mvp life-cycle similar to the pure java approach. Once I get some milage out of this, I'll refactor it with Gin.
Thanks again.
P.S. if you haven't seen the i/o presentation mentioned above, it is worth checking out.