您的位置:首页 > Web前端 > JavaScript

如何使用javascript的PureMVC框架 - Mediator/View层

2012-07-06 19:07 441 查看
本实例的最终源文件下载地址

http://download.csdn.net/detail/laogong5i0/4400288

继续前两次的

如何使用javascript的PureMVC框架 - 初始化

如何使用javascript的PureMVC框架 - Command/controller层

后,我们接下来要学习的是View层,Mediator的使用。

在上次如何使用javascript的PureMVC框架 - Command/controller层时我们曾使用Notification来触发Command的执行,其实Notification在PureMVC随处可以,它不仅可以用来触发Command的执行,在Mediator也是随处可见的!

在Mediator里,你可以发送、接收、声明notification,当Mediator被注册时,Mediator的listNotifications()方法会被调用,以数组形式返回该Mediator对象所关心的所有Notification。之后,当PureMVC其它角色发出同名的Notification(通知)时,关心这个通知的Mediator都会调用handleNotification()方法并将Notification以参数传递到方法。

理论上就说这么多,接下来是上代码!

首先在上两次教程里的html文件里添加一个div标签,内容为

<div align="center">
<form id="userForm">
<label>First Name</label>
<input id="firstNmae" type="iniput" required />
<label>Last Name</label>
<input id="lastNmae" type="iniput" required />
<input id="submit" type="button" value="Submit" />
</form>
</div>
然后在demo文件夹下新建view文件夹,并在view文件夹下新建components文件夹

跟着在components文件夹下新建UiComponent.js以及UserForm.js文件

UiComponent.js文件是一个用于程序的UI组件的基类,它主要添加一个基于UiComponent的实现,让UI组件从Mediators监听

UserForm.js是继承自UiComponent.js类的UI组件,主要是实现对form表单的引用及操作。

UiComponent.js文件内容为

/**
* @class
* 一个用于程序的UI组件的基类
* 它主要添加一个基于UiComponent的实现,让UI组件从Mediators监听
* 实现者和监听者是负责匿名事件对象的发送和接受
*/
var UiComponent = Objs("demo.view.components.UiComponent",
{
/**
* @construct
* 初始化一个UiComponent实例
*/
initialize: function()
{
this.listenerMap = {};
},

/**
* 一个UiComponent.listenerDescriptor的映射对象
* @type {Object}
* @private
*/
listenerMap: null,

/**
* 发送事件到事件流
* @param {String} type
* 		发送的事件类型
* @param {Object} properties
* 		可选的匿名对象,当dispatch时会被发送到事件监听器
*/
dispatchEvent: function( type, properties )
{
if( typeof type == 'undefined' )
return;

if( typeof this.listenerMap[UiComponent.QUEUE_PATTERN + type] == 'undefined' )
return;

var queue/*Array*/ = this.listenerMap[UiComponent.QUEUE_PATTERN + type].slice(0);

var props/*Object*/ = properties || {};
var len/*Number*/ = queue.length;
for(var i/*Number*/=0; i<len; i++)
{
var listenerDescriptor/*UiComponent.ListenerDescriptor*/ = queue[i];

if( typeof listenerDescriptor.listener == 'function' )
{
if( typeof listenerDescriptor.context != "undefined" )
listenerDescriptor.listener.call( listenerDescriptor.context, props );
else
listenerDescriptor.listener.call( this, event, props );
}
}
},

/**
*  添加一个监听器去监听接收事件通知
* @param {String} type
* 		添加的事件类型
* @param {Function} listener
* 		添加事件监听器方法
* @param {Object} context
* 		添加事件监听方法的附加内容
*/
addEventListener: function
(
type,
listener,
context
)
{
if( typeof type == "undefined" )
return;

if( typeof listener == "undefined" )
return;

var newListener/*UiComponent.ListenerDescriptor*/ = new UiComponent.ListenerDescriptor( listener, context );

var queue/*Object*/;
if( typeof this.listenerMap[ UiComponent.QUEUE_PATTERN + type ] == "undefined" )
queue = this.listenerMap[ UiComponent.QUEUE_PATTERN + type ] = [];
else
queue = this.listenerMap[ UiComponent.QUEUE_PATTERN + type ];

var len/*Number*/ = queue.length;
for(var i/*Number*/=0; i<len; i++ )
{
var listenerDescriptor/*UiComponent.ListenerDescriptor*/ = queue[i];
if( listenerDescriptor.equals( newListener ) )
return;
}

queue.push(newListener);
},

/**
* 删除一个事件监听器以便监听器停止接受notification事件
* @param {String} type
* 		删除的事件类型
* @param {Function} listener
* 		删除的事件监听器方法
* @param {Object} context
* 		删除事件监听方法的附加内容
*/
removeEventListener: function
(
type,
listener,
context
)
{
if( typeof type == "undefined" )
return;

if( typeof listener == "undefined" )
return;

if( typeof this.listenerMap[UiComponent.QUEUE_PATTERN + type] == "undefined" )
return;

var queue/*Object*/ = this.listenerMap[ UiComponent.QUEUE_PATTERN + type ];
var len/*Number*/ = queue.length;
for(var i/*Number*/=0; i<len; i++)
{
var listenerDescriptor/*UiComponent.ListenerDescriptor*/ = queue[i];
if( listenerDescriptor.equals( new UiComponent.ListenerDescriptor( listener, context ) ) )
{
queue.splice(i,1);
return;
}
}
}
});

/**
* @class
* @private
* Event对象由UiComponent类派发到它的事件监听器
*/
UiComponent.Event = Objs("demo.view.components.UiComponent.Event",
{
/**
* 事件类型
* @type {String}
*/
type: null,

/**
* 随着dispatche event一起发送的属性
* @type {Object}
*/
properties: null

});

/**
* @private
* 使用UiComoponent.listenerMap描述符对象鉴定各个事件监听器
* 这是Javascript的内部类
*/
UiComponent.ListenerDescriptor = Objs("demo.view.components.UiComponent.Event",
{
/**
* @construct
* 初始化实例
* @param {Function} listener
* 		被调用的方法
* @param {Function} listener
* 		被调用方法的内容
*/
initialize: function( listener, context )
{
this.listener = listener;
this.context = context;
},

/**
* @private
* 对比两UiComponent.ListenerDescriptor 以确定与目标相同的事件监听器。
*
* @param {UiComponent.ListenerDescriptor} compared
*		descriptor将与当前的内容做对比
* @return {Boolean}
* 		两个对比监听的的boolean值
*/
equals: function( compared )
{
if( compared.listener == this.listener )
{
if( typeof compared.context != "undefined" )
{
if( compared.context == null && this.context == null )
return true;

if( compared.context == this.context )
return true;
}
}

return false;
}
});

//一个字符前缀,用于防止项目名冲突
UiComponent.QUEUE_PATTERN = '@_@';


在编写UserForm.js前我们先在demo文件夹下新建一个model文件夹,然后在model文件夹下新建一个vo文件夹来存放user对象类,吧user信息写成一个对象类,方便以后使用,以及程序看起来跟清晰。

在vo文件夹下新建User.js文件夹,内容为

var UserVO = Objs("demo.model.vo.UserVO",
{

firstName: "",
lastName: "",

/*
* 判断用户是否合法
*/
getIsValid: function()
{
return 	this.firstName != ""
&&
this.lastName != ""
;
}

});


接下是UserForm.js内容

var UserForm = Objs("demo.view.components.UserForm",
UiComponent,
{

user: null,
sweepsFields: null,
firstName: null,
lastName: null,
submit: null,
/**
* @construct
* @override
* 初始化UserForm实例.
*/
initialize: function()
{
//调用父类中的initialize函数
UserForm.$super.initialize.call( this );

this.initializeChildren();
this.configureListeners();

this.clearForm();
this.setEnabled(false);

},

/**
* 初始化对html元素的引用
*/
initializeChildren: function()
{
this.sweepsFields = $("#userForm");

this.firstName = this.sweepsFields.find("#firstNmae");
this.lastName = this.sweepsFields.find("#lastNmae");

this.submit = this.sweepsFields.find("#submit").button();
},

/**
* 注册监听事件
*/
configureListeners: function()
{
var that = this;
this.submit.click( function(evt){ that.submit_clickHandler(evt) } );
},

/**
* 设置一个user用来填充表单
* @param {UserVO} user
*/
setUser: function( user )
{
this.user = user;

if( !user )
this.clearForm();
else
{
this.firstName.val(user.firstName);
this.lastName.val(user.lastName);
}
},
/**
* 获取用户
*/
getUser: function()/*UserVO*/
{
this.updateUser();
return this.user;
},

/**
* 根据fields的值更新用户属性
*/
updateUser: function()
{
this.user = new UserVO();
this.user.firstName = this.firstName.val();
this.user.lastName = this.lastName.val();
},

/**
* 清除整个表单
*/
clearForm: function()
{
this.firstName.val("");
this.lastName.val("");
},

/**
* 时用或者禁用form表单
* @param {Boolean} isEnabled
*/
setEnabled: function( isEnabled )
{
if( isEnabled )
{
this.firstName.removeAttr("disabled");
this.lastName.removeAttr("disabled");
}
else
{
this.firstName.attr( "disabled", "disabled" );
this.lastName.attr( "disabled", "disabled" );
}
},

/**
* 按下submit时调用
*/
submit_clickHandler: function()
{
this.updateUser();
//判断user信息是否合法,如果不合法提示并返回
if( !this.user.getIsValid() )
{
alert('Please typing you First Name and Last Name');
return;
}
// 调用基类UiComponent的dispatchEvent方法,派发UserForm.ADD事件
this.dispatchEvent( UserForm.ADD );
},

});

/*
* Event names
*/
UserForm.ADD/*String*/        = "add";


接下来就是在Mediator里面操作UserForm实例了!

在view文件夹下新建UserFormMediator.js文件内容如下,主要功能是按Submit按钮后发送this.sendNotification( NotificationNames.USER_LISTS_ADD_ITEM, user );命了

var UserFormMediator = Objs("demo.view.UserFormMediator",
Mediator,
{

/**
* @construct
* @override
* 初始化UserFormMediator实例
* @param {String} name
*         Mediator的名称
* @param {UserForm} viewComponent
*         Mediator所管理的UserForm视图组件
*/
initialize: function( name, viewComponent )
{
UserFormMediator.$super.initialize.call( this, name, viewComponent );

var userForm = this.getUserForm();
//注册监听事件userForm.ADD,当触发时会调用onAdd方法,即监听submit按钮是否按下
userForm.addEventListener( UserForm.ADD, this.onAdd, this );

var user = new UserVO();
user.firstName='pat';
user.lastName='chen';

userForm.setUser(user);
},

/**
* @private
* 获取UserFrom视图组件
*/
getUserForm : function()
{
return this.viewComponent;
},

/**
* @private
* 当用户按submit时调用
* @param {UiComponent.Event} event
*         The dispatched event object.
*/
onAdd: function( event )
{
var user = this.getUserForm().getUser();
//使用PureMVC发送notification消息
//在这里你需要在上次如何使用javascript的PureMVC框架 - Command/controller层提到的NotificationNames.js文件里添加
//NotificationNames.USER_LISTS_ADD_ITEM = "user_lists_add_item";内容
this.sendNotification( NotificationNames.USER_LISTS_ADD_ITEM, user );
var userForm = this.getUserForm();
userForm.clearForm();
userForm.setEnabled(true);
},

/**
* @override
* 注册时被调用
*/
onRegister: function()
{
},

/**
* @override
* 当本Mediator被移除是被调用
*/
onRemove: function()
{
},
/**
* 把要监听的事件添加到这个数组里去,
* 当this.facade.sendNotification( notice, data);时,就会调用handleNotification();方法
* @override
*/
listNotificationInterests: function()
{
return [
];
},

/**
* 在这里处理使用 this.facade.sendNotification( notice, data);发出来的事件
* @override
*/
handleNotification: function( note )
{
var userForm = this.getUserForm();
var user;
switch ( note.getName() )
{

}
}
});

/*
* Constants
*/
UserFormMediator.ADD/*String*/            = "add";


使用this.sendNotification( NotificationNames.USER_LISTS_ADD_ITEM, user );发出来的消息可以在Mediator 里监听也可一在Command里监听,下面我写再写一个Mediator来监听由UserFormMediator发出来的NotificationNames.USER_LISTS_ADD_ITEM消息。

在view文件夹下新建UserListsMediator.js文件,内容如下

var UserListsMediator = Objs("sweeps.view.UserListsMediator",
Mediator,
{

/**
* @construct
* @override
* 初始化UserListsMediator实例
* @param {String} name
*         Mediator的名称
* @param {UserlistsForm} viewComponent
*         Mediator所管理的UserlistsForm视图组件
*/
initialize: function( name, viewComponent )
{
UserFormMediator.$super.initialize.call( this, name, viewComponent );
},

/**
* 把要监听的事件添加到这个数组里去,
* 当this.facade.sendNotification( notice, data);时,就会调用handleNotification();方法
* @override
*/
listNotificationInterests: function()
{
return [
NotificationNames.USER_LISTS_ADD_ITEM
];
},

/**
* 在这里处理使用 this.facade.sendNotification( notice, data);发出来的事件
* @override
*/
handleNotification: function( note )
{
var data = note.getBody();
switch ( note.getName() )
{
case NotificationNames.USER_LISTS_ADD_ITEM:
alert('firs name: ' + data.firstName + " \nlast name: " + data.lastName);
break;
}
}
});


到这里我们还需要吧写好的Mediator注册到PureMVC中,

在上次如何使用javascript的PureMVC框架 - Command/controller层所提到的PrepViewCommand类里面知道到 execute方法,修改 execute()方法

execute: function( note )
{
//初始化View对象
var userForm = new UserForm();

//初始化Mediator对象
var userFormMediator = new UserFormMediator( 'USER_FORM_MEDIATOR', userForm );
var userListsMediator = new UserListsMediator( 'USER_LISTS_MEDIATOR',null);

//注册Mediators
this.facade.registerMediator( userFormMediator );
this.facade.registerMediator( userListsMediator );
}


最后所有文件的目录树为



那么所有类都写好了!就是剩下吧所有使用到的类导入到html里面了;

<script type="text/javascript" src="src/demo/model/vo/UserVO.js"></script>
<script type="text/javascript" src="src/demo/view/UserFormMediator.js"></script>
<script type="text/javascript" src="src/demo/view/UserListsMediator.js"></script>
<script type="text/javascript" src="src/demo/view/components/UiComponent.js"></script>
<script type="text/javascript" src="src/demo/view/components/UserForm.js"></script>

<script type="text/javascript" src="src/demo/abc/NotificationNames.js"></script>
<script type="text/javascript" src="src/demo/controller/PrepViewCommand.js"></script>
<script type="text/javascript" src="src/demo/controller/StartupCommand.js"></script>
<script type="text/javascript" src="src/demo/ApplicationFacade.js"></script>


这里的类文件比较多,这就是面向对象的特色啦,文件比较多,但当你熟悉后你就不觉得了,反而维护起来很方便。

如果你觉得太多,怕影响浏览速度的话,你只要在发布的时候吧这些文都压缩到一个文件里去就行了,我这里没有压缩,所有看起来比较麻烦。

按一下submit按钮看看吧!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: