我想知道
#MainPlace:eventCalendar?storeId=<id>
等网址为商店的活动日历添加书签?我在这里ActivityMapper
public class AppActivityMapper implements ActivityMapper {
private ClientFactory clientFactory;
private MainActivity mainActivity;
// ..
@Override
public Activity getActivity(Place place) {
if (place instanceof LoginPlace) {
return new LoginActivity((LoginPlace) place, clientFactory);
} else if (place instanceof MainPlace) {
if(this.mainActivity == null) {
this.mainActivity = new MainActivity((MainPlace) place, clientFactory);
} else {
this.mainActivity.updateMainContent(((MainPlace) place).getMainContentToken());
}
return this.mainActivity;
}
return null;
}
}
和MainActivity
控制我的MainView
,它只是左侧的菜单和右侧的主要内容。
我想在Best Practices for Architecting GWT App中解除我的观点,这就是为什么我试图通过使用在MenuView
点击某些内容时被触发的事件来控制主要内容。
因此,我正在MainActivity
初始化一些事件处理程序,这些事件处理程序会对菜单中按钮的点击作出反应,将更新委托给MainView
。
public class MainActivity extends AbstractActivity implements MainView.MainPresenter {
@Override
public void start(AcceptsOneWidget panel, EventBus eventBus) {
this.mainView = this.clientFactory.getMainView();
this.mainView.setPresenter(this);
this.mainView.initialize();
this.eventBus = eventBus;
this.eventBus.addHandler(HomeClickedEvent.TYPE, new HomeClickedHandler() {
@Override
public void onHomeClicked(HomeClickedEvent event) {
goTo(new MainPlace("home"));
}
});
this.eventBus.addHandler(EventCalendarClickedEvent.TYPE, new EventCalendarClickedHandler() {
@Override
public void onEventCalendarClicked(EventCalendarClickedEvent eventCalendarClickedEvent) {
goTo(new MainPlace("eventCalendar?storeId=" + eventCalendarClickedEvent.getStoreId()));
}
});
panel.setWidget(this.mainView.asWidget());
}
@Override
public void goTo(Place place) {
this.clientFactory.getPlaceController().goTo(place);
}
@Override
public void updateMainContent(String currentMainContentToken) {
this.mainView.updateMainContent(currentMainContentToken);
}
}
这个事件被MenuPresenter.clickedEventCalendar()
触发,对MenuView
的相应菜单条目点击做出反应:
public class MenuPresenter implements MenuView.MenuPresenter {
// ..
@Override
public void clickedEventCalendar(Long storeId) {
this.eventBus.fireEvent(new EventCalendarClickedEvent(storeId));
}
}
我真正不喜欢的一件事就是我将参数附加到令牌,例如显示storeId
给出的商店的事件日历:
@Override
public void onEventCalendarClicked(EventCalendarClickedEvent eventCalendarClickedEvent) {
goTo(new MainPlace("eventCalendar?storeId=" + eventCalendarClickedEvent.getStoreId()));
}
对于像GWT这样的问题,有更清洁的解决方案吗?我不喜欢我必须在我的实际活动日历中解析该字符串这一事实。我使用ActivityMapper
错误还是没有其他方法可以做到这一点?
答案 0 :(得分:1)
这个问题应该分成几个单独的问题,但这可能是未来要记住的事情。如果你问一件事,那么更容易回答,而其他人也可以更轻松地找到答案。
无论如何,我可以看到一些改进:
如果您只是想让演示者知道在视图中按下按钮(与该演示者相关联),则通过事件总线发送自定义事件有点过分。根据您的需要,您可以在视图界面中显示按钮:
public interface Display {
HasClickHandlers getButton();
}
然后只需在演示者中注册ClickHandler
即可。
或者,如果您需要在点击时执行与和主持人相关的操作,请在视图中注册ClickHandler
并致电演示者:
// In MainView:
@UiHandler("button")
void handleClick(ClickEvent event) {
// Do some stuff with view,
// like hide a panel or change colour
panel.setVisible(false);
// Let the presenter know that a click event has been fired
presenter.onEventCalendarClicked();
}
你是对的 - 像你提议的那样创建MainPlace
是错误的。您过早地创建令牌 - 这就是与该场所关联的令牌化程序的用途。您应该通过仅将MainPlace
传递给构造函数来创建storeId
- 为什么MainPresenter
(或使用此位置的任何其他类)应该知道如何创建令牌? MainPlace
看起来应该更像这样:
public class MainPlace extends Place {
private final Long storeId;
public MainPlace(Long storeId) {
this.storeId = storeId;
}
public Long getStoreId() {
return storeId;
}
public static class Tokenizer implements PlaceTokenizer<MainPlace> {
@Override
public MainPlace getPlace(String token) {
return new MainPlace(Long.valueOf(token));
}
@Override
public String getToken(MainPlace place) {
return "eventCalendar?storeId=" + place.getStoreId();
}
}
}
现在,创建和解析令牌是Tokenizer
的响应。请记住register it on your PlaceHistoryMapper。