关于Flex Cairngorm中command层与View层的通信及耦合度高的问题的解决

在Cairngorm框架中,view层发送自定义事件,command层再根据事件做相应的处理,View层中的数据通过绑定ModelLocator中的属性实现自动更新。现有的问题是,有时除了更新数据意外,用户需要更多的信息,比如,我需要判断后台返回的数据是否正确,或者,我需要更具返回的数据做下一步的处理。


简单的例子,如果获取的数据不符合用户的需要,我可能需要一个提示框给用户一个提示。提示框应该属于View层的。当然在command层也可以直接import  mx.controls.Alert;  调用Alert.show()方法。


但如果,用户在获取到数据后,要执行View层的另外一个方法,那就比较棘手了。比如,我需要在view层DataGrid删除一个数据,我在view层发送一个删除的事件,command层处理事件会返回一个结果,此时,我在view层就要根据不同的结果往下执行不同方法,比如,失败了我执行一个doFail()的,成功了我doSuccess()。

command如何让View去执行下一步的方法呢?

1.传统的做法(command操纵view的引用)
方法A:将view存入ModelLocator中的属性中,而后在command就可以拿到该view的引用,从而执行view的方法。
这种方法可行,但view与command的耦合在了一起,严重破坏了MVC的松耦合度的要求

		private function onResult_delete(e:ResultEvent):void
		{
			if (e.result != null)
			{
				var result:String=e.result.code as String;
				if (result == "success")
				{
				 	Alert.show("删除成功!");
				 	(_model.userManagerModel.view as Object).doSuccess();

				}
 
			}
			else
			{
				Alert.show("修改失败!");
                               (_model.userManagerModel.view as Object).doFail();
			}

		}

将view存入ModelLocator的_model.userManagerModel.view中,在command强制转换为Object从而拿到view的引用

方法B:用到框架中的ViewHelper和ViewLocator这两个类。
ViewHelper类实现接口IMXMLObject,首先自定义一个ViewHelper,然后在视图中引用它。
 

package domain.app.view{ 
	import com.adobe.cairngorm.view.ViewHelper; 
	public class LoginViewHelper extends ViewHelper{ 
		public function doSomething(){ 
		//do something with the protected property view. 
		} 
	}
} 


 

在视图中实例化这个ViewHelper
<helper:LoginViewHelper id="loginViewHelper"/>
然后就可以在Command中使用这个ViewHelper。

但方法同样存在耦合度高的问题,故 Cairngorm 3版本中已经废弃

2.现有做法(事件通信)
既然Flex基于事件驱动的,既然,view可以发事件给command ,那为什么command 不可以发事件通知给view呢?
当view监听到该事件后,自然就可以继续执行view的其他方法了。那view由谁来做这个command发送过来的事件呢?
此时,CairngormEventDispatcher.getInstance()出场。
首先,在CairngormEvent的子类中MyEvent定义2个事件,一个是处理事件DEL,一个是处理事件的事件DEL_COMPLETE,另外添加一个code变量用来存储DEL结果

	public class MyEvent extends CairngormEvent
	{
		public static const DEL:String = "DEL"; //删除
		public static const DEL_COMPLETE:String = "DEL_COMPLETE"; //删除数据  处理完后处理事件

		
		/*返回参数类型 "success""exist""fail"*/
		public var code:String =""; 
		
		/*事件类型*/
		public var event_type:String="";
		
		public function MyEvent(type:String)
		{
			this.event_type=type;
			
			super(type);
		}
	}

其中DEL是交给command处理的,所以要在FrontController中做一个绑定;DEL_COMPLETE则不需要

			this.addCommand(MyEvent.DEL, UserManagerCommand);


我们在view发事件DEL给command后,立马用CairngormEventDispatcher.getInstance()做一个DEL_COMPLETE事件的监听

command 在处理完DEL后,就发送一个DEL_COMPLETE事件,此时,view在监听这个事件的CairngormEventDispatcher.getInstance()就可以执行相应的方法了

下面是commad的操作

		private function onResult_delete(e:ResultEvent):void
		{
			var event:MyEvent = new MyEvent(MyEvent.DEL_COMPLETE);
			if (e.result != null)
			{
				var result:String=e.result.code as String;
				if (result == "success")
				{
				 	event.code = "success";

				}else{event.code = "fail"
				}
 
			}
			else
			{
				event.code = "fail"
			}
			/*发送处理事件*/
			event.dispatch();

		}


 

下面是view的操作

			private function init():void
			{
 				var e :MyEvent = new MyEvent(MyEvent.DEL);
				e.dispatch();
					
				/* 监听 数据返回 */
				CairngormEventDispatcher.getInstance().addEventListener(MyEvent.DEL_COMPLETE, del_compelete);
				}
			}
			
			/**************************************************************
			 * 函数:command处理完成后执行方法
			 */
			private function del_compelete(e:MyEvent):void
			{
				CairngormEventDispatcher.getInstance().removeEventListener(MyEvent.EDIT_COMPLETE, del_compelete);
				if (e.code =="success"){
					Alert.show("删除成功!");	 doSuccess();				} else 
				if (e.code =="fail"){
					Alert.show("删除失败!");	 doFail();			}							
			}



这样,view和command耦合性的问题得到解决。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值