Как использовать GWT Editor Framework с gwt-платформой?
Я использую gwt-платформу и попытался реализовать каркас редактора GWT. Но я не понимаю, как это работает внутри докладчика. В Интернете есть несколько ответов, в которых говорится, что мне нужно каким-то образом ввести EditorDriver в Presenter, но я не знаю, как это сделать...
На данный момент я попробовал это без успеха:
public class MyPresenter extends Presenter<MyPresenter.MyView, MyPresenter.MyProxy> implements MyUiHandlers {
public interface MyView extends View, HasUiHandlers<MyUiHandlers>, Editor<MyModel> {}
@ProxyStandard
@NameToken(NameTokens.myPage)
@NoGatekeeper
public interface MyProxy extends ProxyPlace<MyPresenter> {}
interface Driver extends SimpleBeanEditorDriver<MyModel, MyView> {}
private Driver editorDriver;
DispatchAsync dispatcher;
@Inject
public MyPresenter(EventBus eventBus, MyView view, MyProxy proxy, DispatchAsync dispatcher) {
super(eventBus, view, proxy);
getView().setUiHandlers(this);
this.dispatcher = dispatcher;
MyModel m = new MyModel();
m.setId(1L);
m.setUsername("username");
m.setPassword("password");
editorDriver = GWT.create(Driver.class);
editorDriver.initialize(this.getView());
editorDriver.edit(m);
}
...
}
Это работает, если я явно указываю ViewImplementation, но MVP не должен работать так:
interface Driver extends SimpleBeanEditorDriver<MyModel, MyViewImpl> {}
...
editorDriver.initialize((MyViewImpl) this.getView());
Я был бы хорош, если бы кто-нибудь мог дать мне пример, как это сделать правильно.
Спасибо
3 ответа
Подход, аналогичный тому, который использовался в более ранней версии образца Расходов, работал для меня:
Интерфейс, который должно реализовать представление. Подстановочный знак используется для того, чтобы докладчику не нужно было знать конкретную реализацию представления:
import com.google.gwt.editor.client.Editor;
import com.gwtplatform.mvp.client.View;
/**
* Implemented by views that edit beans.
*
* @param <B> the type of the bean
*/
public interface BeanEditView<B> extends View, Editor<B> {
/**
* @return a new {@link SimpleBeanEditorDriver} initialized to run
* this editor
*/
SimpleBeanEditorDriver<B, ?> createEditorDriver();
}
Ваш докладчик должен выглядеть примерно так:
public class MyPresenter extends Presenter<MyPresenter.MyView, MyPresenter.MyProxy> implements MyUiHandlers {
public interface MyView extends BeanEditView<MyModel>, HasUiHandlers<MyUiHandlers> {}
@ProxyStandard
@NameToken(NameTokens.myPage)
@NoGatekeeper
public interface MyProxy extends ProxyPlace<MyPresenter> {}
private SimpleBeanEditorDriver<MyModel, ?> editorDriver;
DispatchAsync dispatcher;
@Inject
public MyPresenter(EventBus eventBus, MyView view, MyProxy proxy, DispatchAsync dispatcher) {
super(eventBus, view, proxy);
getView().setUiHandlers(this);
this.dispatcher = dispatcher;
MyModel m = new MyModel();
m.setId(1L);
m.setUsername("username");
m.setPassword("password");
editorDriver = getView().createEditorDriver();
}
...
}
И мнение о реализации
public class MyViewImpl extends ViewWithUiHandlers<MyUiHandlers> implements
MyPresenter.MyView {
public interface Binder extends UiBinder<Widget, MyViewImpl> { }
private static Binder uiBinder = GWT.create(Binder.class);
/**
* The driver to link the proxy bean with the view.
*/
public interface EditorDriver extends SimpleBeanEditorDriver<MyModel, MyViewImpl> { }
private final Widget widget;
public MyViewImpl() {
widget = uiBinder.createAndBindUi(this);
}
@Override
public SimpleBeanEditorDriver<MyModel, ?> createEditorDriver() {
EditorDriver driver = GWT.create(EditorDriver.class);
driver.initialize(this);
return driver;
}
@Override
public Widget asWidget() {
return widget;
}
...
}
Это как можно ближе к MVP с помощью GWT Editor Framework. Я не смог найти способ реализации представления, чтобы НЕ знать модель, но я не думаю, что это действительно необходимо.
Если у кого-то есть улучшения по этому поводу, я рад слышать.
Нашел некоторые дополнительные комментарии на GWT Editors. Кажется, что может быть просто невозможно полностью отделить модель. Как говорит Томас Бройер в своем ответе на другой вопрос редактора:
"MVP не заложен в камень (он даже не определен; он был придуман Мартином Фаулером, но он отказался от термина в пользу двух более конкретных моделей), так что вы нарушаете только те правила, которые вы дали себе. Иными словами, Фреймворк редактора в целом можно рассматривать как нарушающий MVP: каждый редактор знает модель, не обязательно точный экземпляр, который она редактирует (как в случае с ValueAwareEditor или LeafValue), но по крайней мере вид объектов, для которых он является редактором ".
Проблема в том, что Driver.class передан в GWT.create
editorDriver = GWT.create(Driver.class);
должен конкретный класс, который содержит все подредакторы, то есть все uibinded виджеты.
Одним из решений является следующее:
Интерфейс представления расширяет интерфейс редактора для объекта Model
public interface MyView extends View, ..., Editor<MyModel>
Реализация представления MyViewImpl определяет тип драйвера
interface MyDriverImpl extends SimpleBeanEditorDriver<MyModel,MyViewImpl>
Драйвер создается в MyViewImpl
SimpleBeanEditorDriver<MyModel,MyView> driver = GWT.create(MyDriverImpl.class);
Родительский тип
SimpleBeanEditorDriver<MyModel,MyView>
может использоваться для передачи рекомендаций водителя докладчику
MVP говорит, что вы используете презентатор, чтобы полностью отделить модель от вида. Кроме того, я бы сказал, что ваш подход помещает логику в представление... Я надеюсь, что есть другое решение;)