GXT之旅:第七章:MVC——GXT MVC的相关类

AppEvent class

AppEvent负责承载着信息,在controller和view之间。每个AppEvent对象都会有一个专门的EventType定义。

AppEvent对象可以随意的通过setData方法,承载一个或多个datas。这样很有益于传递状态信息。当设置多个Datas的时候,我们就需要使用key-value键值对,把每个Data命名,以方便检索。

另外一个功能就是,可是使用setHistoryEvent方法,在设置AppEvent的历史事件。这就意味着,当一个事件被派发出去的时候,该之间就会被设置成历史事件。这一特性的设计,方便在dispatcher里查询历史事件。

EventType class

EventType是用来定义事件类型的,具体来说是给AppEvent起名子的。具有代表性的,我们会在AppEvents类里,定义一些列的静态fields,器field的类别就是EventType。

下面,我们就在RSSReader项目,定义应用事件

  • 新建package:com.danielvaughan.rssreader.client.mvc.events,新建类AppEvents
  • 在AppEvents类里,定义两个EventType的fields

package com.danielvaughan.rssreader.client.mvc.events;

import com.extjs.gxt.ui.client.event.EventType;

public class AppEvents {
	public static final EventType Init = new EventType();
	public static final EventType Error = new EventType();
}

Controller class

Controller在应用里,承担着对事件响应和处理的角色。

一个Controller在其构造函数里,必须注册EventTypes,才可以监听事件。registerEventTypes方法就是用通过传入EventType参数,完成注册过程!

  • 新建package:com.danielvaughan.rssreader.client.mvc.controllers,在此包下,新建类AppController继承Controller
  • 在构造函数里,完成事件注册

package com.danielvaughan.rssreader.client.mvc.controllers;

import com.danielvaughan.rssreader.client.mvc.events.AppEvents;
import com.extjs.gxt.ui.client.mvc.AppEvent;
import com.extjs.gxt.ui.client.mvc.Controller;

public class AppController extends Controller {
	public AppController() {
		registerEventTypes(AppEvents.Init);
		registerEventTypes(AppEvents.Error);
	}

	@Override
	public void handleEvent(AppEvent event) {
		
		
	}
}

当继承抽象类Controller的时候,必须要实现handleEvent抽象方法。此方法是用来定义如何处理不同EventType的。

如果想要查询一个Controller是否可以处理某个专门的AppEvent的时候,可以使用canHandle方法。


响应一个事件的处理流程如下:

  • 事件出入总的controller
  • 然后将事件派发到具体的某一个子controller
  • 将事件转发到view,等待后续的操作
  • 将如上三步整合起来。

接下来,我们要在RSSReader项目实现,AppController的handleEvent方法。

  • orverride handleEvent 方法
  • 目前,我们不需要在Controller层处理任何的事件,只是将所有的事件转发到view层。因此,我们需要定义一个View

private com.extjs.gxt.ui.client.mvc.View appView;

  • 随着View的定义,我们将所有的evet都转发到view里——实现一个forward的功能。

package com.danielvaughan.rssreader.client.mvc.controllers;

import com.danielvaughan.rssreader.client.mvc.events.AppEvents;
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 AppController extends Controller {

	private View appView;

	public AppController() {
		registerEventTypes(AppEvents.Init);
		registerEventTypes(AppEvents.Error);
	}

	@Override
	public void handleEvent(AppEvent event) {

		forwardToView(appView, event);
	}
}


View class

View是GXT MVC架构中一部分。负责提供用户接口——显示可视化组件,响应从Controller转发过来的事件,当然也负责响应用户操作所产生的事件(AppEvents),并将其派发到Dispatcher。

正如controllers一样,views也需要实现handleEvent方法。为了保持代码整洁易懂,最好针对每一个EventType去创建一个on<EventType>方法。

比如,如果我们想要处理Init的EventType 。我们需要在handleEvent里检查其EventType,并调用对应的处理方法onInit。

protected void handleEvent(AppEvent event) {
    EventType eventType = event.getType();
    if (eventType.equals(AppEvents.Init)) {
        onInit(event);
    }
}

接下来,我们在RSSReader项目里,实现View层的代码

  • 新建package:com.danielvaughan.rssreader.client.mvc.views,在此包下,新建AppView继承View
  • 别忘了,orverride handleEvent方法

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 AppView extends View {

	public AppView(Controller controller) {
		super(controller);

	}

	@Override
	protected void handleEvent(AppEvent event) {

	}

}

  • 注意,如上的构造函数的写法。其原因是View没有无参的,空方法体的构造函数!java基础啦害羞
  • 正如我们之前介绍的:注册了两个事件Init和Error,那么就要有对应的on<EventType>方法

private void onInit(AppEvent event) {}
private void onError(AppEvent event) {}

  • 现在,要实现handleEvent方法里面具体的内容——根据EventType跳转到对应的处理方法。

	@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);
		}
	}

  • 最后,我们需要让AppController和AppView之间有关联。通过override Appcontroller的 initialize方法实现。这样当AppView里面的事件才会通过此关联操作,跳转到AppController中去!

package com.danielvaughan.rssreader.client.mvc.controllers;

import com.danielvaughan.rssreader.client.mvc.events.AppEvents;
import com.danielvaughan.rssreader.client.mvc.views.AppView;
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 AppController extends Controller {

	private View appView;

	public AppController() {
		registerEventTypes(AppEvents.Init);
		registerEventTypes(AppEvents.Error);
	}

	@Override
	public void handleEvent(AppEvent event) {

		forwardToView(appView, event);
	}

	@Override
	public void initialize() {
		super.initialize();
		appView = new AppView(this);
	}
}


package com.danielvaughan.rssreader.client.mvc.views;

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.View;

public class AppView extends View {

	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);
		}
	}

	private void onInit(AppEvent event) {
	}

	private void onError(AppEvent event) {
	}
}

Dispatcher class

Dispatcher是一个单独的类——是一个单实例的对象,穿梭于整个应用。他有着static的方法用来转发AppEvent对象。一个Controller需要通过Dispatcher去注册,然后监听不同EventType的AppEvent。当一个AppEvent被派发的时候,就会根据先前注册监听的EventType去唤醒AppEvent。

一个事件可以在程序的任何地方被唤醒,只是需要Dispatcher的forwardEvent方法。如下有四个forwardEvent方法的重载,方便用户调用。

MethodDescription
forwardEvent(AppEvent event)将现有的AppEvent派发出去。
forwardEvent(EventType eventType)根据EventType,会新建一个AppEvent,再派发出去。
forwardEvent(EventType eventType, java.
lang.Object data)
根据EventType新建AppEvent,作为一个载体,装载一个object,并派发出去。
forwardEvent(EventType eventType, java.
lang.Object data, boolean historyEvent)
根据EventType新建AppEvent,装载一个object。并标记的AppEvent是否是一个历史事件,最后派发出去。

除了上述static的方法之外,Dispatcher同样还有非静态的dispatch方法。当然功能上是相同的。实是上,这些static的forwardEvent方法就是调用那些非静态的dispatch方法。唯一不同的是,在这些非静态的dispach方法里,没有上述的第四个方法。

如果Dispatcher有多个controllers被注册了,那么他同样会唤醒所有的AppEvent,其顺序是按照当时注册的顺序执行。我们要注意到这一执行顺序,尤其是在Controller的handleEvent方法处理AppEvent的时候。


总结整个GXT MVC功能集

GXT MVC 的实现步骤如下:

  1. 派发(Dispatcher)不同类型的EventType
  2. 监听 Dispatcher(派发器)
  3. 接收事件,处理事件
  4. 定义不同类型的AppEvent
  5. 程序处理:转发AppEvent到派发器
  6. 程序处理:用户操作,触发了事件
  7. 程序处理:将事件注册到Controllers里
  8. 程序处理:将Controllers注册到派发器里(Dispatcher)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值