第六章:快速有效地使用Cairngorm和Flex开发 之二

CairngormStore 需求列表

客户除了可以把产品从商店加入到购物篮外,也可以使用需求列表feature来存放他们以后想要买的产品。

使用tab接口,客户可以选择把产品放入到购物篮或是需求列表。当客户购买购物篮中的产品时,在需求列表中的产品不会出现。

客户可以使用拖曳产品的图标或是产品列表的描述的方法加入到需求列表,也可以拖曳产品细则面板中的图标的方法加入到需求列表,还可以按产品细则面板中的“添加”按钮的方法加入到需求列表中。

注意:这种需求不能规定客户可能把物品在需求列表和检验中互相移动。现在假设这种需求是额外的story。

在用户经历之前,这不值得一提。选择tab接口是功能的一种,由J2EE开发人员实现。在现实世界的工程里,我会使用考虑用户经验,结合需求列表,更加有效地加入到全部的信息架构中去。

作为一种典型的灵活工作,开发人员通常将一个story分为一些小任务。使用Cairngorm微架构,存在于feature中的任务变得更加可见,可重用。你可能记得在第四章中我讨论过基于feature驱动的开发。

对于上述的需求列表story,我建议story中的任务是这样的:

在前台控制器类中注册一个新的事件addProductToWishList

创建一个新一命令AddProductToWishList来响应事件。

在模型定位器中创建一个WishList对象

实现视图:

将WishList对象加入到Tab Navigator控制中去,跟Shopping Card对象同个地方

动态绑定WishList对象到模型定位器中。

当用户按下“添加到需求列表”按钮时,广播用户动作到前台控制器。

当用户拖曳和放下产品到需求列表对象时,广播用户动作到前台控制器。

让我们遵循这些任务来编码吧!

在前台控制器类中注册事件

第一步是给基于Cairngorm应用程序简要的描述一下,当用户想要把产品加入到他们的需求列表中时,一个新的用户动作就会发生了。

CairngormStore有它自己的前台控制实例,ShopController.as,你可以使用它注册所有可能的CairngormStore命令。

首先,你必须把事件的名称加入到ShopController

public static var EVENT_ADD_PRODUCT_TO_WISH_LIST = "addProductToWishList";

记住,使用static类型定义事件的名称,你可以在编译时间检查事件被广播时是否合法。这确保当被广播为black-hole之前你没发现事件名称拼写错误时,你的应用程序也不会失败。

接着,你必须注册一个命令类来响应这个事件。这个工作只要在initialiseCommands()方法中加入新的实例:

addCommand( ShopController.EVENT_ADD_PRODUCT_TO_WISH_LIST, new AddProductToWishListCommand() );

这就是前台控制器类实例关心的。现在它认识新的事件,它也知道当这个事件发生时怎么做。

再接下来,你要创建命令类来响应这个事件:AddProductToWishList 命令类。

创建AddProductToWishListCommand命令类

让我们来看看新命令类的代码,它很简单,不需要加以说明:

import org.nevis.cairngorm.commands.Command;

import org.nevis.cairngorm.control.Event;

import org.nevis.cairngorm.samples.store.model.ModelLocator;

import org.nevis.cairngorm.samples.store.vo.ProductVO;



class org.nevis.cairngorm.samples.store.command.AddProductToWishListCommand implements Command

{

public function execute( event : Event ):Void

{

   var product : ProductVO = ProductVO( event.data.product );

   var quantity : Number = Number( event.data.quantity );

   ModelLocator.wishList.addElement( product, quantity );

}

}

这代码一点也不复杂…execute()方法是一个独立的命令实例指针,当ShopController. EVENT_ADD_PRODUCT_TO_WISH_LIST发生时,由前台控制器调用。

Execute()方法简单地添加了适当的产品数量包括当用户按下“添加到需求列表”时将需求列表对象加入到模型定位器。

再是,你现在可以假定用户接口,视图,通过Flex数据绑定到在模型定位器中的需求列表对象。这就是业务逻辑形式下所有要做的事。

下一步是确定我们有需求列表对象在模型定位器上。

存储需求列表对象到模型定位器

Cairngorm使得Flex的开发很简单。自从你有ShoppingCart类在CairngormStore中管理产品列表和这些产品的数量时,你完全可以简单地重用这个类来实现需求列表对象。需求列表对象毕竟是一个简单的ShoppingCart,你不必要对这个特别的访问做检查。

下面是加入到ModelLocator.as的代码:

非常简单,你创建一个新的ShoppingCart实例,然后调用需求列表实例。你在模型定位器的构造器中创建新的实例,如下:

ModelLocator.wishList = new ShoppingCart();

假设你在模型定位器中其它定义中声明了需求列表实例,像这样:

public static var wishList : ShoppingCart;

这真的是全部的工作。你是否感到你可以快速地向Cairngorm应用程序加入新的feature。

实现视图

这样我们创建了一个命令类,在前台控制器类中注册,当产品加入到需求列表中时它更新模型定位器类,你重用了业务对象(ShoppingCart)来实现我们的需求列表。

在为需求列表创建用户接口时剩下的问题就是确保它动态地绑定到模型定位器中的动态数据,确保事件ShopController.EVENT_ADD_PRODUCT_TO_WISH_LIST在任何用户动作发生时返回结果。

将需求列表加入到视图

我将替换屏幕的一部分,只用包含两个ShoppingCart MXML组件的Tab Navigator显示ShoppingCart MXML组件。第一个实例是我们原始的ShoppingCart,而第二个则是需求列表。

当用户发出添加产品到需求列表的动作时,你将改变ProductDetails组件来截获,就像添加产品到ShoppingCart一样。这就需要ProductDetails MXML组件要有一个addProductToWishList事件,下面是代码:

这个简单的需求,只要改动一下SideArea.mxml,如下:

<details:ProductDetails

        id="productDetailsComp"

        width="100%" height="325"

        currencyFormatter="{ ModelLocator.currencyFormatter }"

        selectedItem="{ ModelLocator.selectedItem }"          

        addProduct="addProductToShoppingCart( event )"

        addProductToWishList="addProductToWishList( event )" />                   



<mx:TabNavigator width="100%" height="100%">



<!-- the Shopping Cart -->         

<cart:ShoppingCart

        id="shoppingCartComp"

        label="Shopping Cart"

        width="100%" height="100%"

        shoppingCart="{ ModelLocator.shoppingCart }"

        selectedItem="{ ModelLocator.selectedItem }"

        select="ModelLocator.selectedItem = event.target.selectedItem"

        currencyFormatter="{ ModelLocator.currencyFormatter }"

        addProduct="addProductToShoppingCart( event );"

        deleteProduct="deleteProductFromShoppingCart( event );"

        gotoCheckout="ModelLocator.workflowState =

                      ModelLocator.VIEWING_CHECKOUT;" />   



<!-- the Wish List -->

<cart:ShoppingCart

        id="wishListCartComp"

        label="Wish List"

        width="100%" height="100%"

        shoppingCart="{ ModelLocator.wishList }"

        selectedItem="{ ModelLocator.selectedItem }"

        select="ModelLocator.selectedItem = event.target.selectedItem"

        currencyFormatter="{ ModelLocator.currencyFormatter }"

        addProduct="addProductToWishList( event );"

        deleteProduct="deleteProductFromShoppingCart( event );"

        gotoCheckout="ModelLocator.workflowState =

                      ModelLocator.VIEWING_CHECKOUT;" />



</mx:TabNavigator>

ShoppingCart实例被在Tab Navigator 中的wishListCartComp调用。

首先,wishListCartComp实例数据绑定到ModelLocator.wishList,接着wishListModel上的任何改动都会自动影响Shopping Cart组件内部。这是acion中一个大组件重用的好例子。

addProduct事件调用了一个方法,addProductToWishList(),你需要在SideArea.mxml中定义,如下:

private function addProductToWishList( event : Object ) : Void

{      

EventBroadcaster.getInstance().broadcastEvent(

    ShopController.EVENT_ADD_PRODUCT_TO_WISH_LIST, event );

}



这个方法很好地将用户动作翻译成适当的Cairngorm事件;现在,当用户把产品放入ShoppingCart组件中的WishListCartComp实例时,被认为是添加到WishList的用户动作,这个动作被翻译成适当的Cairngorm事件。

我们在ProductDetails MXML组件中使用addProductToWishList()方法,如下使用:

addProductToWishList="addProductToWishList( event )"

很明显,这要求ProductDetails MXML组件能广播addProductToWishList事件效果就像是按下“添加到WishList”发生的事件一样。这样最后视图部分代码如ProductDetails.mxml

首先,在ProductDetails上更新MetaData定义要广播的新的事件,如下显示:

<mx:Metadata>

   [Event("addProduct")]

   [Event("addProductToWishList")]

</mx:Metadata>

最后,声明新的按钮,将它的点击事件变为更有意义的业务事件,addProductToWishList。声明一个有用的方法来广播addProductToWishList事件及附加的信息:产品被添加(当前选择的产品)和用户需要的数量:

private function addProductToWishList() : Void

{

var event : Object = new Object();

event.type = "addProductToWishList";

event.product = selectedItem;

event.quantity = quantity;

dispatchEvent( event );

}

你可以加入你一个新的按钮”添加到购物篮”来代替加入到需求列表,代码如下:

<mx:Button label="Add to Cart" click="addProduct();" />

<mx:Button label="Add to WishList" click="addProductToWishList();" />

这是一个很好的示例我们在第三章讨论过:把一个按钮的点击事件转变为一个更有意义的事件来表示我们的业务领域("addProductToWishList"),轻松地构建MXML组件。这样ProductDetails和SideArea MXML组件通过被广播,绑定不同的事件。

这就是它了。现在你已经加入了全部代码到MXML来表示用户操作需求列表的流程。通过动态绑定MXML到模型定位器类和将用户动作翻译成Cairngorm事件,视图被绑定在最底层的Cairngorm架构结构上。

你可能感兴趣的:(数据结构,工作,Flex,领域模型)