我正在尝试使用分离的模型,视图和演示者构建gwt小部件。
到目前为止,我只使用了一个类用于所有这些组件:
一个紧凑的例子:
public class MyCellSelectableTable extends Composite {
private WhatEverRepresentation selectedCell;
public MyCellSelectableTable() {
Grid myTable = new Grid(2,2);
/*
* Some code to realize a table with cell selection
* ...
*/
initWidget(myTable);
}
}
在我看来,“selectedCell”(以及我项目中的许多其他数据)的信息应该存储在一个单独的模型中。 我怎样才能在结构上正确实现这一点,所以它仍然是一个小部件但是有一个封装的mvp架构?
答案 0 :(得分:2)
在我的一个项目中,我被要求设计一个旋转项目,该项目在移动网络应用程序上看起来很好看。然后我们意识到我们实际上需要另一个我们的旋转器视图,它也是“更薄”的。所以我试图将MVP方法应用于我的小部件实现,这对我来说很有用。下面这个是一个非常简单的例子,不仅仅是为了演示而用于生产
以MVP模式定义Presenter和View界面。这里的要点是使视图实现变得愚蠢,以便可以毫不费力地切换它们。请注意,Spinner实际上并不是一个Widget,但它实现了IsWidget,这意味着它将被视为一个小部件,但事实上我们将传递视图实现的引用。
public class Spinner implements IsWidget, SpinnerPresenter{
interface View{
Widget asWidget();
void stepUp(int step);
void stepDown(int step);
void setValue(int value);
void setPixelSize(int width,int height);
}
View view;
int value;
public Spinner() {
view = new SpinnerImpl(this);
view.setValue(0);
}
public int getValue() {
return value;
}
public void setValue(int value) {
if (value == this.value)
return;
this.value = value;
view.setValue(value);
}
public void setPixelSize(int width, int height){
view.setPixelSize(width,height);
}
@Override
public void downButtonClicked() {
value--;
view.stepDown(1);
}
@Override
public void upButtonClicked() {
value++;
view.stepUp(1);
}
@Override
public Widget asWidget() {
return view.asWidget();
}
}
视图实现本身实现了Spinner类中定义的视图接口。请注意我们如何将用户事件委托给Spinner类,以便通过SpinnerPresenter接口进行处理。
public class SpinnerImpl extends Composite implements Spinner.View{
private TextBox txtBox;
private Button upButton,downButton;
private HorizontalPanel panel;
private SpinnerPresenter presenter;
public SpinnerImpl(SpinnerPresenter presenter){
this.presenter = presenter;
upButton = new Button("up");
downButton = new Button("down");
txtBox = new TextBox();
txtBox.setEnabled(false);
panel = new HorizontalPanel();
panel.add(upButton);
panel.add(txtBox);
panel.add(downButton);
addHandlers();
initWidget(panel);
}
private void addHandlers() {
upButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
presenter.upButtonClicked();
}
});
downButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
presenter.downButtonClicked();
}
});
}
@Override
public void stepDown(int step) {
txtBox.setValue(Integer.parseInt(txtBox.getValue())-1+"");
}
@Override
public void stepUp(int step) {
txtBox.setValue(Integer.parseInt(txtBox.getValue())+1+"");
}
@Override
public void setValue(int value) {
txtBox.setValue(0+"");
}
}
SpinnerPresenter界面:
public interface SpinnerPresenter {
void upButtonClicked();
void downButtonClicked();
}
最后将我的小部件添加到rootpanel。请注意,我可以添加微调器类,就好像它是一个小部件
Spinner s = new Spinner();
RootPanel.get().add(s);
现在,如果我想改变我的微调器项目的外观,改变方向,可能为旋转等添加一个奇特的动画,我只需要更改我的View实现。最后但并非最不重要的是,在测试我的小部件时,这种方法将有所帮助,因为我可以轻松地模拟我的视图。
答案 1 :(得分:0)
我建议您阅读以下MVP文章,如果您还没有(如果有的话,请原谅我): http://code.google.com/webtoolkit/articles/mvp-architecture.html http://www.gwtproject.org/articles/mvp-architecture.html
请相信我,继续将您的模型,视图和演示者分开是值得的。这个问题在一个课程中似乎总是很简单,但是当我尝试过时,我总是把事情分开。您会感谢您更好地分离关注点和提供的灵活性。
答案 2 :(得分:0)
仅供参考,GWT中的单元小部件是在内部使用MVP构建的。 CellList
(例如)是“视图”部分并实例化内部演示者。
此外,Google I / O 2010的这次会议让我大开眼界:http://www.google.com/events/io/2010/sessions/gwt-continuous-build-testing.html