上一节,在程序的入口文件(RSSReader),我们派发了EventType为Init的AppEvent,AppController会处理此事件,将其转发到AppView。依次的,AppView会的处理该事件,去调用onInit方法,完成基础的UI创建。在此过程中负责了程序主体的区域创建。但是,唯一没有处理的,就是没有把组装好的components添加到UI。
那么现在,我们需要再分别创建几组Controller和View,分别去负责RSSReader项目其他的各个区域。首先我们要创建一对Controller-View,去处理Navigation区域。
大致思路如下:
此前,onModuleLoad方法里已经派发了UIReady事件。因此,NavPanel应该已经被添加到Viewport里,显示出来。具体实现步骤如下:
public static final EventType NavPanelReady = new EventType();
package com.danielvaughan.rssreader.client.mvc.controllers; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; public class NavController extends Controller { @Override public void handleEvent(AppEvent event) { } }
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 NavView extends View { public NavView(Controller controller) { super(controller); } @Override protected void handleEvent(AppEvent event) { } }
public NavController() { registerEventTypes(AppEvents.Init); }
package com.danielvaughan.rssreader.client.mvc.controllers; import com.danielvaughan.rssreader.client.mvc.events.AppEvents; import com.danielvaughan.rssreader.client.mvc.views.NavView; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; public class NavController extends Controller { private NavView navView; public NavController() { registerEventTypes(AppEvents.Init); } @Override public void handleEvent(AppEvent event) { forwardToView(navView, event); } @Override public void initialize() { super.initialize(); navView = new NavView(this); } }
package com.danielvaughan.rssreader.client.mvc.views; import com.danielvaughan.rssreader.client.components.NavPanel; 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 NavView extends View { private final NavPanel navPanel = new NavPanel(); public NavView(Controller controller) { super(controller); } @Override protected void handleEvent(AppEvent event) { } }
package com.danielvaughan.rssreader.client.mvc.views; import com.danielvaughan.rssreader.client.components.NavPanel; import com.danielvaughan.rssreader.client.mvc.events.AppEvents; import com.extjs.gxt.ui.client.event.EventType; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; import com.extjs.gxt.ui.client.mvc.Dispatcher; import com.extjs.gxt.ui.client.mvc.View; public class NavView extends View { private final NavPanel navPanel = new NavPanel(); public NavView(Controller controller) { super(controller); } @Override protected void handleEvent(AppEvent event) { EventType eventType = event.getType(); if (eventType.equals(AppEvents.Init)) { Dispatcher.forwardEvent(new AppEvent(AppEvents.NavPanelReady, navPanel)); } } }
public AppController() { registerEventTypes(AppEvents.Init); registerEventTypes(AppEvents.Error); registerEventTypes(AppEvents.UIReady); registerEventTypes(AppEvents.NavPanelReady); }
package com.danielvaughan.rssreader.client.mvc.views; import com.danielvaughan.rssreader.client.mvc.events.AppEvents; import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.Style.Orientation; import com.extjs.gxt.ui.client.event.EventType; import com.extjs.gxt.ui.client.mvc.AppEvent; import com.extjs.gxt.ui.client.mvc.Controller; import com.extjs.gxt.ui.client.mvc.View; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.Viewport; import com.extjs.gxt.ui.client.widget.layout.BorderLayout; import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData; import com.extjs.gxt.ui.client.widget.layout.RowLayout; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.RootPanel; public class AppView extends View { private final ContentPanel mainPanel = new ContentPanel(); private final Viewport viewport = new Viewport(); public AppView(Controller controller) { super(controller); } @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); } } private void onInit(AppEvent event) { final BorderLayout borderLayout = new BorderLayout(); viewport.setLayout(borderLayout); HTML headerHtml = new HTML(); headerHtml.setHTML("<h1>RSS Reader</h1>"); BorderLayoutData northData = new BorderLayoutData(LayoutRegion.NORTH, 20); northData.setCollapsible(false); northData.setSplit(false); viewport.add(headerHtml, northData); BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER); centerData.setCollapsible(false); RowLayout rowLayout = new RowLayout(Orientation.VERTICAL); mainPanel.setHeaderVisible(false); mainPanel.setLayout(rowLayout); viewport.add(mainPanel, centerData); } private void onUIReady(AppEvent event) { RootPanel.get().add(viewport); } private void onNavPanelReady(AppEvent event) { BorderLayoutData westData = new BorderLayoutData(LayoutRegion.WEST, 200, 150, 300); westData.setCollapsible(true); westData.setSplit(true); Component component = event.getData(); viewport.add(component, westData); } private void onError(AppEvent event) { } }
@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.dispatch(AppEvents.Init);会派发Init事件,虽然只是执行了一次派发操作,但是会派发到多个controller中去! // 原因:因为AppController和NavController都注册了Init ! // 顺序:两个controller的接收到event的顺序是根据上面的两行代码(controller的加入顺序)有关! dispatcher.dispatch(AppEvents.Init); dispatcher.dispatch(AppEvents.UIReady); }