Gwt 活动处理程序不';不要被移除
我正在努力跟上使用GWT活动和场所的速度。我正在使用一些源代码进行测试,这些源代码最初是在这本书上找到的 我发现在bind()期间添加的处理程序似乎从未被删除。我对这个函数的一点理解让我认为,在调用活动的onStop()方法时,应该自动删除它们 在此之前,它注册的所有事件处理程序都将被删除 方法被调用 但是每次我点击一个按钮,相应的处理程序就会被调用n+1次 我错过了什么?请让我知道,如果有更多的信息,我可以提供 下面是代码中的一个相关片段:Gwt 活动处理程序不';不要被移除,gwt,gwt-mvp,Gwt,Gwt Mvp,我正在努力跟上使用GWT活动和场所的速度。我正在使用一些源代码进行测试,这些源代码最初是在这本书上找到的 我发现在bind()期间添加的处理程序似乎从未被删除。我对这个函数的一点理解让我认为,在调用活动的onStop()方法时,应该自动删除它们 在此之前,它注册的所有事件处理程序都将被删除 方法被调用 但是每次我点击一个按钮,相应的处理程序就会被调用n+1次 我错过了什么?请让我知道,如果有更多的信息,我可以提供 下面是代码中的一个相关片段: public class ContactsActiv
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));
}
}
});
}
公共类ContactsActivity扩展了AbstractActivity{
私人名单联系人详情;
专用最终联系人服务异步RPC服务;
专用最终事件总线事件总线;
私人最终IContactsViewDisplay显示;
私募股权控制人;
公共接口IContactsView显示{
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getList();
无效设置数据(列表数据);
int getClickedRow(单击事件事件);
列出getSelectedRows();
Widget asWidget();
}
公共联系活动(客户工厂){
GWT.log(“ContactActivity:constructor”);
this.rpcService=factory.getContactServiceRPC();
this.eventBus=factory.getEventBus();
this.display=factory.getContactsView();
this.placeController=factory.getPlaceController();
}
@凌驾
公共void启动(AcceptsOneWidget容器,EventBus EventBus){
log(“ContactActivity:start()”;
bind();
container.setWidget(display.asWidget());
fetchContactDetails();
}
公共无效绑定(){
log(“ContactActivity:bind()”;
display.getAddButton().addClickHandler(新建ClickHandler()){
公共作废一次点击(点击事件){
GWT.log(“单击添加按钮”);
ContactsActivity.this.placeController.goTo(NewContactPlace(“”);
}
});
display.getDeleteButton().addClickHandler(新建ClickHandler()){
公共作废一次点击(点击事件){
日志(“ContactActivity:单击删除按钮”);
deleteSelectedContacts();
}
});
display.getList().addClickHandler(新建ClickHandler()){
公共作废一次点击(点击事件){
日志(“ContactActivity:List clicked”);
int selectedRow=display.getClickedRow(事件);
如果(selectedRow>=0){
String id=contactDetails.get(selectedRow.getId();
ContactsActivity.this.placeController.goTo(新的EditContactPlace(id));
}
}
});
}
通过注册的事件。传递到AbstractActivity#start()
的EventBus
将在调用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();
}
}
公共类ContactsActivity扩展了AbstractActivity{
私有列表注册=新建ArrayList();
私有无效绑定(){
registrations.add(display.getAddButton()。
addClickHandler(新建ClickHandler(){…}));
registrations.add(display.getDeleteButton()。
addClickHandler(新建ClickHandler(){…}));
registrations.add(display.getList()。
addClickHandler(新建ClickHandler(){…}));
}
@凌驾
公共void onStop(){
用于(HandlerRegistration:注册){
registration.removeHandler();
}
注册。清除();
}
}
我发现最好在视图中处理注册-让它只负责为每个按钮激活一个点击手柄
而不是:
class View {
Button commitButton;
public HasClickHandlers getCommit () {return commitButton;}
}
…并在活动中链接到:
view.getCommit.addClickHandler(new Clickhandler()...
view.setCommitHandler (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.getCommit.addClickHandler(new Clickhandler()...
view.setCommitHandler (new ClickHandler () ...
希望这能有所帮助。非常感谢您的建议。我现在可以在onStop()中注销处理程序。在AbstractActivity#start()中通过EventBus传递处理程序是否更常见、更好?除了使用@UiHandler之外,这是如何完成的?EventBus用于应用程序间事件,而不是UI事件。您的操作是正确的。