0

我在我的 gwt 项目中使用 mvp4g。对于我的一位演示者,我正在使用选项multiple=true,并且我正在以这种方式创建和绑定演示者:

ObjectPresenter mainObject = eventBus.addHandler(ObjectPresenter.class, false);
mainObject.setId(id);
mainObject.bind();
view.addWidget(mainObject.getView().asWidget());

ObjectPresenter 扩展了 LazyPresenter。

当我从eventBus被捕获的 中调用第一个事件时,再次调用的ObjectPresenter方法。bind()LazyPresenter

bind方法在树内有其他方法:createPresenter(); view.createView(); bindView();. 在我通过添加下一个小部件来修改我的视图的bindView方法中。ObjectPresenter因为该方法被调用了两次(一次由我直接调用,一次由框架调用)一些小部件被复制。

我已经调试了代码,我发现BaseEventHandler当调用来自的事件时,这部分代码eventBus被调用:

public final boolean isActivated( boolean passive, String eventName, Object... parameters ) {
    boolean activated = this.activated && pass( eventName, parameters );
    if ( activated ) {
        if ( passive ) {
            return binded;
        } else {
            onBeforeEvent();
            if ( !binded ) {
                bind();
                binded = true;
            }
        }
    }
    return activated;
}

直接调用bind(通过mainObject.bind())绑定属性后BaseEventHandler未设置为true,因此bind在调用第一个事件时再次调用方法。

我可以在方法(直接调用)完成时从 to 设置变量,但binded我不确定这是否是正确的方法......BaseEventHandlertrueObjectPresenterbind

你能给我一个提示如何处理这个问题吗?

谢谢你的帮助。

4

2 回答 2

0

我没有仔细阅读文档!我正在使用方法eventBus.addHandler(ObjectPresenter.class, false)(带bind参数),它具有以下 java 文档。

     /**
     * Create a new instance of the handler, bind it only if this option is set to true and add it
     * to event bus. If you decide not to bind the handler at creation, you will have either make
     * sure the handler is displayed only after it handles its first method (otherwise the view is
     * not binded so it seems inactive) or call manualy the bind method.<br/>
     * <br/>
     * When binding the handler, you have to call the isActivated method. This method will be called
     * with eventName and parameters set to null.
     * 
     * @param <T>
     *            type of the handler created
     * @param handlerClass
     *            class of the handler to create
     * @param bind
     *            if true, bind the handler at creation, otherwise do nothing.
     * @return new instance of the handler created
     * 
     * @throws Mvp4gException
     *             thrown if the instance of the handler can not be created by the event bus
     */
    <E extends EventBus, T extends EventHandlerInterface<E>> T addHandler( Class<T> handlerClass, boolean bind ) throws Mvp4gException;

我错过的部分是绑定处理程序时,您必须调用 isActivated 方法。此方法将在 eventName 和参数设置为 null 的情况下调用。那是我的问题——我没有这样做!

于 2014-07-22T17:27:13.237 回答
0

首先的问题,你真的需要multiple=true-featrue。此功能旨在一次使用同一演示者类的多个实例。如果这不是您的情况,请不要使用它,因为您必须编写大量代码,这些代码通常由 mvp4g-framework 生成。

此外,您永远不应该bind直接调用 - 方法。

如果您需要多重功能,您可以创建一个处理程序(扩展BaseHandler类)。此处理程序应管理您的演示者实例。编码应包含您的演示者实例列表:

  private List<EventHandlerInterface<MyEventBus>> presenters = new ArrayList<EventHandlerInterface<MyEventBus>>();

要显示一个新实例,甚至将一个现有实例放在前面,处理程序应该监听一个事件(这里eventBus.showObject([someNumber]);::

public void onShowObject(long id) {
  // check if a presenter for that Id already exists
  if (presenters.size() > 0) {
    for (int i = 0; i < presenters.size(); i++) {
      ObjectPresenter presenter = (ObjectPresenter) presenters.get(i);
      if (presenter.getId() == idNr) {
        eventBus.setCurrentObject(presenter.getView().asWidget());
        return;
      }
    }
  }
  // no presenter found, create a new one and add the presetner instance to the list 
  ObjectPresenter mainObject = eventBus.addHandler(ObjectPresenter.class);
  mainObject.setId(id);
  presenters.add(mainObject);
  eventBus.setCurrentObject(mainObject.getView().asWidget());
}

}

该事件setCurrentObject(Widget widget)将使您的视图可见。所以你的 shell 也必须作为演示者/视图组合来实现,它必须监听setCurrentObject(Widget widget)-event。使用此代码,您无需调用bind- 方法。

我将在几个项目中使用此代码,它的效果非常好。此外,使用此代码进行历史管理非常容易。

希望有帮助。

于 2014-06-19T14:56:10.767 回答