mvp4g LazyPresenter с опцией множественный =true связывается дважды
Я использую mvp4g в моем проекте gwt. Для одного из моих докладчиков я использую опцию 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
метод вызывается снова, когда вызывается первое событие.
Я могу установить binded
переменная из BaseEventHandler
в true
в ObjectPresenter
когда метод bind
(вызвано напрямую) закончено, но я не уверен, что это правильный подход...
Не могли бы вы дать мне подсказку, как бороться с этой проблемой?
Спасибо за вашу помощь.
2 ответа
Я недостаточно внимательно прочитал документацию! Я использовал метод 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;
Часть, которую я пропустил: При связывании обработчика вы должны вызвать метод isActivation. Этот метод будет вызываться с eventName и параметрами, установленными в нуль. и это была моя проблема - я этого не делал!
Прежде всего вопрос, вам действительно нужно 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)
сделает ваш взгляд видимым. Таким образом, ваша оболочка также должна быть реализована как комбинация презентатор / представление, которая должна прослушивать setCurrentObject(Widget widget)
-событие. Используя этот код, вам не нужно вызывать bind
-метод.
Я буду использовать этот код в нескольких проектах, и он работает очень хорошо. Кроме того, с этим кодом довольно легко использовать управление историей.
Надеюсь, это поможет.