Как использовать 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 говорит, что вы используете презентатор, чтобы полностью отделить модель от вида. Кроме того, я бы сказал, что ваш подход помещает логику в представление... Я надеюсь, что есть другое решение;)

Другие вопросы по тегам