21.5.创建Cairngorm视图、事件和模型

21.5.1.问题
我需要创建一个Cairngorm视图,并把它绑定到模型的属性上。
21.5.2.解决方案
创建一个实现了Cairngorm ModelLocator接口的模型类,往这个类里添加需要的数据属性,并把这些属性标记为可绑定的。然后把视图中所有数据驱动的控件绑定到这个模型的对应属性上。
21.5.3.讨论
Cairngorm控制器的视图不需要扩展任何类,它可以是任意类型。视图最重要的特征是它们绑定到模型类的属性上,并且当需要从服务器加载数据或者需要向服务器发送数据时,它们会触发CairngormEvent。

接下来的几部分将创建一个Cairngorm应用程序,我们将按照书写的顺序而不是开发的顺序一步步显示它们。这个程序的视图包括:一个mx:Button,点击它会生成一个加载recipes的事件,该事件会调用服务并加载recipes;一个DataGrid,用来显示从服务器收到的结果:
+展开
-XML
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxmlwidth="400height="300">
<mx:Script>
<![CDATA[
import
oreilly.cookbook.cairngorm.events.RecipeEvent;
import oreilly.cookbook.cairngorm.model.Model;
/*在下面的方法中,会发送RecipeEvent,该事件使得FrontController接收来自服务器的数据,我们不需要知道服务器究竟是从数据库中读取数据还是从其他地方读取。更多关于FrontController的信息,请查看21.8小节。而现在,我们关心的是视图和视图发送的通知应用程序获取数据的事件。另外需要注意的是,CairngormEvent类有一个dispatch方法,用来把它们发送到Cairngorm EventDispatcher上。这跟通常情况下处理事件的方式不同,需要确保事件被FrontController处理而不是被其他的截获。*/
privatefunction loadRecipes():void{
var evt:RecipeEvent = newRecipeEvent(RecipeEvent.GET_RECIPE);
evt.recipeKeywords= recipeKeywords.text.split("," );
//Note that the CairngormEvent class dispatches itself
//This notifies the Cairngorm EventBroadcaster that the event
//is being dispatched. This is used to ensure that the Cairngorm architecture
//handles the event rather than the flash.events.EventDispatcher
evt.dispatch();
}

]]>
</mx:Script>
<mx:VBox>
<mx:TextInput id="recipeKeywords"/>
<mx:Button label="Load Recipesclick="loadRecipes()"/>
<!--Cairngorm程序视图的另一个重要特征是它绑定到模型上。下面的例子中recipeArray是服务器返回的数据数组,它保存在模型中,视图就绑定到它上面。这样不需要把视图暴露给服务相关的逻辑,就能在数据加载到应用程序时更新视图。-->
<mx:DataGrid dataProvider="{Model.getInstance().recipeArray}">
<mx:columns>
<mx:DataGridColumn dataField="title"/>
<mx:DataGridColumn dataField="difficulty"/>
<mx:DataGridColumn dataField="pictureURL">
<mx:itemRenderer>
<mx:Component>
<mx:Image source="{data}"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn dataField="preparationTime"/>
<mx:DataGridColumn dataField="ingredients"/>
<mx:DataGridColumn dataField="instructions"/>
</mx:columns>
</mx:DataGrid>
</mx:VBox>
</mx:Canvas>

RecipeEvent类有两个功能。一个是向服务器发送关键字以在数据库中搜索相关的内容。另一个功能是通知FrontController创建一个命令去接收来自服务器的数据,并把数据保存到模型中。Cairngorm中自定义的动作必须拥有它自己的事件。这样才能保证所有需要服务器端通信的事件都用不同的事件类型,FrontController也好利用它们决定应该调用哪个命令。

Cairngorm事件定义了需要发送到服务器的所有数据,另外还有用来区分不同事件类型的一个或多个字符串常量。尽管在Flex 1.5 Cairngorm0.99版本中推荐每个需要service call的事件都应该有一个独立的事件类型,但是最近,开发者会在一个CairngormEvent类中使用多个事件类型。我个人比较喜欢在单个类中有多个事件类型,当然你怎么做由你决定。
+展开
-ActionScript
package oreilly.cookbook.cairngorm.events {
import com.adobe.cairngorm.control.CairngormEvent;
public class RecipeEvent extendsCairngormEvent {
public static const GET_RECIPE:String= "getRecipe" ;
//this will be all the keywords for our recipe and is stored here so it
//can be sent to the service for processing
public var recipeKeywords:Array;
public function RecipeEvent(type:String,bubbles:Boolean=false,cancelable:Boolean=false){
super(type, bubbles, cancelable);
}
}
}

最后,下面的部分显示的是实现了ModelLocator接口的模型。ModelLocator接口并没有对实现它的类定义任何方法,但是要确保Cairngorm应用程序的模型类应该有一个可以用来识别它的类型:
+展开
-ActionScript
package oreilly.cookbook.cairngorm.model {
import com.adobe.cairngorm.model.ModelLocator;
import mx.collections.ArrayCollection;
public class Model implementsModelLocator {
// A way to get typed arrays
[Bindable]
[ArrayElementType("oreilly.cookbook.cairngorm.vo.Recipe")]
public var recipeArray:ArrayCollection;
public static function getInstance():Model{
if(inst == null)
{
inst = new Model();
}
returninst;
}
protected static var inst:Model;
}
}

加支付宝好友偷能量挖...


评论(0)网络
阅读(90)喜欢(0)flash/flex/fcs/AIR