MVP在 Flex中的应用
关于MVP是MVC的另一种模式,在MVP模式中视图和模型是完全分离的,他们通过Presenter进行交互。
Presenter与控制器非常相似,但是它们也有一些的区别:
1、Presenter处理视图发送过来的用户操作(在MVC中视图自己处理了这些操作)
2、它用更新过的数据去更新模型(在被动MVC中控制器只是通知视图去更新过的模型中去取新的数据,而主动MVC中模型通知视图去更新显示,控制器不需要做工作)
3、检查模型的更新(与被动MVC一样)
4、(与MVC的主要区别)从模型中取数据然后将它们发送到视图中
5、(与MVC的主要区别)将所做的更新告知视图
6、(与MVC的区别)用Presenter渲染视图
其图如下:
MVP的优势:
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所以的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presener用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)。
下面是Flex 的MVP实现
package com.vniu.view
{
public interface IUserView{
function set userName(value:String):void;
function set lastName(value:String):void;
function set city(value:String):void;
function set errorMessage(value:String):void;
function get searchCriteria():String;
}
}
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="350" height="200" implements="com.vniu.view.IUserView" creationComplete="init()"
backgroundColor="#A0D2FD" backgroundAlpha="0.5">
<mx:Script>
<![CDATA[
import com.vniu.presenter.UserViewPresenter;
private var _presenter:UserViewPresenter;
private function init():void{
_presenter = new UserViewPresenter(this);
}
public function set userName(value:String):void{
_userName.text = value;
}
public function set lastName(value:String):void{
_lastName.text = value;
}
public function set city(value:String):void{
_city.text = value;
}
public function get searchCriteria():String{
return _searchCriteria.text;
}
public function set errorMessage(value:String):void{
_errorMessage.text = value;
_errorMessage.visible = value != "";
}
]]>
</mx:Script>
<mx:Label text="Contact Details Manager" width="100%" fontWeight="bold"/>
<mx:Label id="_errorMessage" width="100%" color="#FF0006"/>
<mx:Form width="100%" height="50%">
<mx:FormItem label="Name" width="100%">
<mx:TextInput id="_userName" editable="false" width="100%"/>
</mx:FormItem>
<mx:FormItem label="Surname" width="100%">
<mx:TextInput id="_lastName" editable="false" width="100%"/>
</mx:FormItem>
<mx:FormItem label="City" width="100%">
<mx:TextInput id="_city" editable="false" width="100%"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%">
<mx:Label text="Insert a code to search" />
<mx:TextInput width="120" id="_searchCriteria" restrict="0-9" />
<mx:Button label="search" click="_presenter.recoverData()" />
</mx:HBox>
</mx:VBox>
package com.vniu.presenter
{
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
import com.vniu.view.IUserView;
public class UserViewPresenter{
private var _view:IUserView;
private var _xdata:XML;
private const DATA_FILE:String = "data/users.xml";
public function UserViewPresenter(view:IUserView) {
_view = view;
var url:URLRequest = new URLRequest(DATA_FILE);
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onDataRead);
loader.load(url);
}
private function onDataRead(e:Event):void{
_xdata = XML(e.target.data);
}
public function recoverData():void{
if(_view.searchCriteria == ""){
_view.errorMessage = "Insert a code please!";
}else{
var data:XMLList = _xdata.customer.(@code == _view.searchCriteria);
if(data.length() == 0){
_view.errorMessage = "No user found!";
_view.userName = "";
_view.lastName = "";
_view.city = "";
}else{
_view.userName = data.firstName.text();
_view.lastName = data.lastName.text();
_view.city = data.city.text();
_view.errorMessage = "";
}
}
}
}
}