一个AppEvent不仅仅可以被一个Controller所捕捉,它可以被多个Controller所捕捉,关键在于有多少个Controller注册了该AppEvent。
下面我们要结合之前代码,新建一个新的StatusController,注册之前已有的Events,使用StatusToolbar component来给用户显示系统的运行状态。
我们现在针对两个以后的事件:
- Feed selected
- Item selected
下面具体实现步骤如下:
- AppEvents类里,加入新的EventType定义——StatusToolbarReady
public static final EventType StatusToolbarReady = new EventType();
- 在com.danielvaughan.rssreader.client.mvc.controllers包下,新建类——StatusController。具体内容如下
package com.danielvaughan.rssreader.client.mvc.controllers;
import com.danielvaughan.rssreader.client.mvc.events.AppEvents;
import com.danielvaughan.rssreader.client.mvc.views.StatusView;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
public class StatusController extends Controller {
private StatusView statusView;
public StatusController() {
registerEventTypes(AppEvents.Init);
registerEventTypes(AppEvents.Error);
registerEventTypes(AppEvents.UIReady);
registerEventTypes(AppEvents.FeedSelected);
registerEventTypes(AppEvents.ItemSelected);
}
@Override
public void handleEvent(AppEvent event) {
forwardToView(statusView, event);
}
@Override
public void initialize() {
super.initialize();
statusView = new StatusView(this);
}
}
- 在com.danielvaughan.rssreader.client.mvc.views包下,新建StatusView。具体实现如下
package com.danielvaughan.rssreader.client.mvc.views;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;
import com.extjs.gxt.ui.client.mvc.View;
public class StatusView extends View {
public StatusView(StatusController statusController) {
super(statusController);
}
@Override
protected void handleEvent(AppEvent event) {
}
}
- 新建好后,再定义两个新的属性——Status和ToolBar。在定义一个新的方法,用来设置Status的显示内容
private final Status status = new Status();
private final ToolBar toolBar = new ToolBar();
public void setStatus(String message) {
status.setText(message);
}
- 继续在StatusView类里,新建方法onInit,用来对应Init事件处理。其内容一部分是装配Status和ToolBar;另一部分是派发StatusToolbarReady事件,并携带刚刚装配好的toolBar
private void onInit() {
status.setWidth("100%");
status.setBox(true);
toolBar.add(status);
Dispatcher.forwardEvent(new AppEvent(AppEvents.StatusToolbarReady,
toolBar));
}
- 自然的,要在handleEvent方法里编写Init事件的流程控制。
@Override
protected void handleEvent(AppEvent event) {
EventType eventType = event.getType();
if (eventType.equals(AppEvents.Init)) {
onInit();
setStatus("Init");
}
}
- 针对于*Ready的事件,其捕捉的Controller都是AppController,因此要在AppController注册StatusPanelReady
public AppController() {
registerEventTypes(AppEvents.Init);
registerEventTypes(AppEvents.Error);
registerEventTypes(AppEvents.UIReady);
registerEventTypes(AppEvents.NavPanelReady);
registerEventTypes(AppEvents.FeedPanelReady);
registerEventTypes(AppEvents.ItemPanelReady);
registerEventTypes(AppEvents.StatusToolbarReady);
}
- 随着AppController里有新的事件被注册了,因此就要在响应的View里编写事件的处理方法——编辑AppView类,新建onStatusToolbarReady方法,其内容是把AppEvent所携带的Component,加入到mainPanel里显示出来~~~
private void onStatusToolbarReady(AppEvent event) {
Component component = event.getData();
mainPanel.setBottomComponent(component);
}
- 编辑AppView类handleEvent方法,针对StatusPanelReady事件的流程处理。
@Override
protected void handleEvent(AppEvent event) {
EventType eventType = event.getType();
if (eventType.equals(AppEvents.Init)) {
onInit(event);
} else if (eventType.equals(AppEvents.Error)) {
onError(event);
} else if (eventType.equals(AppEvents.UIReady)) {
onUIReady(event);
} else if (eventType.equals(AppEvents.NavPanelReady)) {
onNavPanelReady(event);
} else if (eventType.equals(AppEvents.FeedPanelReady)) {
onFeedPanelReady(event);
} else if (eventType.equals(AppEvents.ItemPanelReady)) {
onItemPanelReady(event);
}else if (eventType.equals(AppEvents.StatusToolbarReady)) {
onStatusToolbarReady(event);
}
}
- 好像大家都忘了,事件需要被某些Controllers里注册,同样的Controllers也需要在应用里注册!编辑整个应用的入口类——RSSReader,注册StatusController
@Override
public void onModuleLoad() {
final FeedServiceAsync feedService = GWT.create(FeedService.class);
Registry.register(RSSReaderConstants.FEED_SERVICE, feedService);
Dispatcher dispatcher = Dispatcher.get();
dispatcher.addController(new AppController());
dispatcher.addController(new NavController());
dispatcher.addController(new FeedController());
dispatcher.addController(new ItemController());
dispatcher.addController(new StatusController());//here
dispatcher.dispatch(AppEvents.Init);
dispatcher.dispatch(AppEvents.UIReady);
}
- 回归到StatusView类,开始编写针对FeedSelected事件的处理。(因为StatusController在最后被注册,所以FeedSelected事件会先被派发到FeedController,最后才是StatusController。)
@Override
protected void handleEvent(AppEvent event) {
EventType eventType = event.getType();
if (eventType.equals(AppEvents.Init)) {
onInit();
setStatus("Init");
} else if (eventType.equals(AppEvents.FeedSelected)) {
Feed feed = event.getData();
setStatus("Feed Selected - (" + feed.getTitle() + ")");
}
}
- 相似的,在StatusView类,编写针对ItemSelected事件的处理。
@Override
protected void handleEvent(AppEvent event) {
EventType eventType = event.getType();
if (eventType.equals(AppEvents.Init)) {
onInit();
setStatus("Init");
} else if (eventType.equals(AppEvents.FeedSelected)) {
Feed feed = event.getData();
setStatus("Feed Selected - (" + feed.getTitle() + ")");
} else if (eventType.equals(AppEvents.ItemSelected)) {
Item item = event.getData();
setStatus("Item Selected - (" + item.getTitle() + ")");
}
}
- 运行效果如下: