#gwt #gwt-mvp
#gwt #gwt-mvp
Вопрос:
Я пытаюсь ускорить использование действий и мест GWT. Я тестирую с некоторым исходным кодом, первоначально найденным в этом хорошем сообщении в блоге.
Я обнаружил, что обработчики, которые добавляются во время bind(), похоже, никогда не удаляются. Мое небольшое понимание Activity javadoc заставило меня подумать, что они должны автоматически удаляться к моменту вызова метода onStop() Activity .
Все зарегистрированные обработчики событий будут удалены до вызова этого метода.
Но каждый раз, когда я нажимаю кнопку, соответствующий обработчик вызывается n 1 раз.
Чего мне не хватает? Пожалуйста, дайте мне знать, если я могу предоставить больше информации.
Вот соответствующий фрагмент кода:
public class ContactsActivity extends AbstractActivity {
private List<ContactDetails> contactDetails;
private final ContactsServiceAsync rpcService;
private final EventBus eventBus;
private final IContactsViewDisplay display;
private PlaceController placeController;
public interface IContactsViewDisplay {
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getList();
void setData(List<String> data);
int getClickedRow(ClickEvent event);
List<Integer> getSelectedRows();
Widget asWidget();
}
public ContactsActivity(ClientFactory factory) {
GWT.log("ContactActivity: constructor");
this.rpcService = factory.getContactServiceRPC();
this.eventBus = factory.getEventBus();
this.display = factory.getContactsView();
this.placeController = factory.getPlaceController();
}
@Override
public void start(AcceptsOneWidget container, EventBus eventBus) {
GWT.log("ContactActivity: start()");
bind();
container.setWidget(display.asWidget());
fetchContactDetails();
}
public void bind() {
GWT.log("ContactActivity: bind()");
display.getAddButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("Add button clicked");
ContactsActivity.this.placeController.goTo(new NewContactPlace(""));
}
});
display.getDeleteButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("ContactActivity: Delete button clicked");
deleteSelectedContacts();
}
});
display.getList().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("ContactActivity: List clicked");
int selectedRow = display.getClickedRow(event);
if (selectedRow >= 0) {
String id = contactDetails.get(selectedRow).getId();
ContactsActivity.this.placeController.goTo(new EditContactPlace(id));
}
}
});
}
Ответ №1:
События, зарегистрированные через. EventBus
переданные в AbstractActivity#start()
будут незарегистрированы к моменту onStop()
вызова. Однако обработчики событий, зарегистрированные в приведенном выше bind()
методе, не регистрируются через EventBus
и не видны абстрактному базовому классу. Вам нужно отменить их регистрацию самостоятельно:
public class ContactsActivity extends AbstractActivity {
private List<HandlerRegistration> registrations = new ArrayList();
private void bind() {
registrations.add(display.getAddButton().
addClickHandler(new ClickHandler() { ... }));
registrations.add(display.getDeleteButton().
addClickHandler(new ClickHandler() { ... }));
registrations.add(display.getList().
addClickHandler(new ClickHandler() { ... }));
}
@Override
public void onStop() {
for (HandlerRegistration registration : registrations) {
registration.removeHandler();
}
registrations.clear();
}
}
Комментарии:
1. большое спасибо за ваше предложение. теперь я могу отменить регистрацию обработчиков в onStop() . является ли более распространенной и лучшей практикой передавать обработчики через EventBus в AbstractActivity#start()? как это делается, кроме использования @UiHandler?
2. Шина событий предназначена для событий между приложениями, а не для событий пользовательского интерфейса. Вы все делаете правильно.
Ответ №2:
Я обнаружил, что лучше всего обрабатывать регистрацию в представлении — сделать ее ответственной только за то, чтобы для каждой кнопки был активен только один клик.
Вместо:
class View {
Button commitButton;
public HasClickHandlers getCommit () {return commitButton;}
}
.. и ссылка на это в действии:
view.getCommit.addClickHandler(new Clickhandler()...
Сделайте это в представлении:
class View {
private Button commitButton;
private HandlerRegistration commitRegistration = null;
public void setCommitHandler (ClickHandler c) {
commitRegistraion != null ? commitRegistration.removeRegistration ();
commitRegistration = commitButton.addClickHandler (c);
}
}
И активность:
view.setCommitHandler (new ClickHandler () ...
Надеюсь, это поможет.