云自無心水自閑

          天平山上白云泉,云自無心水自閑。何必奔沖山下去,更添波浪向人間!
          posts - 288, comments - 524, trackbacks - 0, articles - 6
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          The major change to this release is how Cairngorm is being packaged. Cairngorm 2.1 introduced a dependency on fds.swc, which isn't part of the standard Flex SDK - it is part of FDS. So, we've repackaged Cairngorm into the core Cairngorm and Cairngorm Enterprise - this also starts aligning Cairngorm with Steven Webster's presentation at Max when he spoke about the Cairngorm Roadmap. We're also now going to to distribute Cairngorm in Binary form (SWC), as a source zip and a documentation zip.

          * Removed dependency on Flex Data Services (fds.swc) - externalised to Cairngorm Enterprise
          * Flex SDK SWCs are no longer linked into Cairngorm.swc (produces a smaller cairngorm.swc)
          * Added support for setting remote credentials
          * Fixed bug with Web services not loading the WSDL (no need to call loadWSDL() explicitly)
          * ModelLocator interface has been deprecated. Added com.adobe.cairngorm.model.IModelLocator
          * Added deprecation metadata for compiler support

          對于我來說,關注的只有一點:ModelLocator被改成IModelLocator了。
          其他的只是Cairngorm的打包方式而已。
          Cairngorm2.1中依賴于fds.swc,而fds.swc不是Flex SDK中的東西,是FDS的一部分。
          在2.2中會將Cairngorm拆成兩部分:Core Cairngorm和Cairngorm Enterprise
          和FDS.swc相關的部分放入Cairngorm Enterprise中。

          posted @ 2007-01-25 21:08 云自無心水自閑 閱讀(1202) | 評論 (2)編輯 收藏

          首先在這個版本中,修正了數百個Bug

          1. 添加對Mac的支持
          2. 支持Eclipse 3.2,而不是僅僅支持3.1
          3. 運行時的CSS支持
          4. 增加了一個Mercury的插件,支持自動測試
          5. 其他一些很棒的功能:包括FlashType的字體和ASDoc的支持。

          posted @ 2007-01-21 13:54 云自無心水自閑 閱讀(513) | 評論 (0)編輯 收藏

          1. 要把database.properties和mail.properties拷貝到build/classes
          2. 要在數據庫中建立test用戶
          3. ant db-create建立數據庫
          4. ant db-prepare建立數據表
          5. ant db-load 將數據插入到數據表中
          6. 修改myapp\build\classes\META-INF目錄中的applicationContext-hibernate.xml
          添加
          ??? <bean id="propertyConfigurer"
          ??? ??? class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          ??? ??? <property name="location"><value>database.properties</value></property>
          ??? </bean>

          ??? <bean id="dataSource"
          ??? ??? class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          ??? ??? <property name="driverClassName">
          ??? ??? ??? <value>${hibernate.connection.driver_class}</value>
          ??? ??? </property>
          ??? ??? <property name="url">
          ??? ??? ??? <value>${hibernate.connection.url}</value>
          ??? ??? </property>
          ??? ??? <property name="username">
          ??? ??? ??? <value>${hibernate.connection.username}</value>
          ??? ??? </property>
          ??? ??? <property name="password">
          ??? ??? ??? <value>${hibernate.connection.password}</value>
          ??? ??? </property>
          ??? </bean>
          7. 修改myapp\build\class\META-INF目錄下的applicationContext-service.xml
          將其中的mail.host, mail.username, mail.password, mail.default.from
          三個變量修改成合適的值
          8. ant deploy
          9. 啟動tomcat, http://localhost:8080/myapp
          10. 輸入mraible,密碼tomcat,進入系統

          posted @ 2007-01-17 01:50 云自無心水自閑 閱讀(366) | 評論 (1)編輯 收藏

          這個函數只是一個示例函數,演示如何遍歷一個Tree。
          此函數嚴格說起來其實是兩個函數:上半部分用于回溯父節點,下半部分遞歸遍歷子節點

          /**
          ?* This method will traverse a Tree's model independent of it's
          ?* type.
          ?*
          ?* <p>Note :: This method may look long and arduous but, rest assured
          ?* it has all the checks to perform like a champ. Also, you 'could'
          ?* refactor part of this method but, for the sake of explanation, I
          ?* kept it all in one place.</p>
          ?*
          ?* <p>Remember, I had coupled the model to this method by tracing
          ?* @label, obviously you do not need to do this. The intention of
          ?* this example is to show you that the dataDescriptor seperates
          ?* the models type and is awesome. It enables you to create a tight
          ?* method like this without type checks on the model.</p>
          ?*
          ?* @param tree The Tree instance that will be examined by the method.
          ?* @param item An item found in the dataProvider of the Tree passed in.
          ?* @param startAtParent A boolean that determines if the method upon
          ?* initialization will back up one leve3l to the item passed in and
          ?* start it's recursion at the item's parent node.
          ?*/

          public function walkTree(tree:Tree, item:Object, startAtParent:Boolean = false):void
          {
          ? ? // get the Tree's data descriptor
          ? ? var descriptor:ITreeDataDescriptor = tree.dataDescriptor;
          ? ? var cursor:IViewCursor;
          ? ?
          ? ? var parentItem:Object;
          ? ? var childItem:Object;
          ? ? var childItems:Object;
          ? ?
          ? ? // if the item is null, stop
          ? ? if(item == null)
          ? ? ? ? return;
          ? ? ? ?
          ? ? // do we back up one level to the item's parent
          ? ? if(startAtParent)
          ? ? {
          ? ? ? ? // get the parent
          ? ? ? ? parentItem = tree.getParentItem(item);
          ? ? ? ? // is the parent real
          ? ? ? ? if(parentItem)
          ? ? ? ? {
          ? ? ? ? ? ? trace("|-- Parent Node ", parentItem[tree.labelField]);
          ? ? ? ? ? ? // if the parent is a branch
          ? ? ? ? ? ? if(descriptor.isBranch(parentItem))
          ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? // if the branch has children to run through
          ? ? ? ? ? ? ? ? if(descriptor.hasChildren(parentItem))
          ? ? ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? ? ? // get the children of the branch
          ? ? ? ? ? ? ? ? ? ? // this part of the algorithm contains the item
          ? ? ? ? ? ? ? ? ? ? // passed
          ? ? ? ? ? ? ? ? ? ? childItems = descriptor.getChildren(parentItem);
          ? ? ? ? ? ? ? ? }
          ? ? ? ? ? ? }
          ? ? ? ? ? ? // if the branch has valid child items
          ? ? ? ? ? ? if(childItems)
          ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? // create our back step cursor
          ? ? ? ? ? ? ? ? cursor = childItems.createCursor();
          ? ? ? ? ? ? ? ? // loop through the items parent's children (item)
          ? ? ? ? ? ? ? ? while(!cursor.afterLast)
          ? ? ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? ? ? // get the current child item
          ? ? ? ? ? ? ? ? ? ? childItem = cursor.current;

          ? ? ? ? ? ? ? ? ? ? var label:String = childItem[tree.labelField];
          ? ? ? ? ? ? ? ? ? ? var branch:Boolean = descriptor.isBranch(childItem);
          ? ? ? ? ? ? ? ? ? ?
          ? ? ? ? ? ? ? ? ? ? // good place for a custom method()
          ? ? ? ? ? ? ? ? ? ? trace("Sibling Nodes :: ", label, "Is Branch :: ", branch);
          ? ? ? ? ? ? ? ? ? ?
          ? ? ? ? ? ? ? ? ? ? // if the child item is a branch
          ? ? ? ? ? ? ? ? ? ? if(descriptor.isBranch(childItem))
          ? ? ? ? ? ? ? ? ? ? ? ? // traverse the childs branch all the way down
          ? ? ? ? ? ? ? ? ? ? ? ? // before returning
          ? ? ? ? ? ? ? ? ? ? ? ? walkTree(tree, childItem);
          ? ? ? ? ? ? ? ? ? ? // do it again!
          ? ? ? ? ? ? ? ? ? ? cursor.moveNext();
          ? ? ? ? ? ? ? ? }
          ? ? ? ? ? ? }
          ? ? ? ? }
          ? ? }
          ? ? else// we don't want the parent OR this is the second iteration
          ? ? {
          ? ? ? ? // if we are a branch
          ? ? ? ? if(descriptor.isBranch(item))
          ? ? ? ? {
          ? ? ? ? ? ? // if the branch has children to run through
          ? ? ? ? ? ? if(descriptor.hasChildren(item))
          ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? // get the children of the branch
          ? ? ? ? ? ? ? ? childItems = descriptor.getChildren(item);
          ? ? ? ? ? ? }
          ? ? ? ? ? ?
          ? ? ? ? ? ? // if the child items exist
          ? ? ? ? ? ? if(childItems)
          ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? // create our cursor pointer
          ? ? ? ? ? ? ? ? cursor = childItems.createCursor();
          ? ? ? ? ? ? ? ? // loop through all of the children
          ? ? ? ? ? ? ? ? // if one of these children are a branch we will recurse
          ? ? ? ? ? ? ? ? while(!cursor.afterLast)
          ? ? ? ? ? ? ? ? {
          ? ? ? ? ? ? ? ? ? ? // get the current child item
          ? ? ? ? ? ? ? ? ? ? childItem = cursor.current;

          ? ? ? ? ? ? ? ? ? ? var label:String =? childItem[tree.labelField];
          ? ? ? ? ? ? ? ? ? ? var branch:Boolean = descriptor.isBranch(childItem);
          ? ? ? ? ? ? ? ? ? ?
          ? ? ? ? ? ? ? ? ? ? // good place for a custom method()
          ? ? ? ? ? ? ? ? ? ? trace("-- Sub Node :: ", label, "Is Branch :: ", branch);

          ? ? ? ? ? ? ? ? ? ? // if the child item is a branch
          ? ? ? ? ? ? ? ? ? ? if(descriptor.isBranch(childItem))
          ? ? ? ? ? ? ? ? ? ? ? ? // traverse the childs branch all the way down
          ? ? ? ? ? ? ? ? ? ? ? ? // before returning
          ? ? ? ? ? ? ? ? ? ? ? ? walkTree(tree, childItem);
          ? ? ? ? ? ? ? ? ? ? // check the next child
          ? ? ? ? ? ? ? ? ? ? cursor.moveNext();
          ? ? ? ? ? ? ? ? }
          ? ? ? ? ? ? }
          ? ? ? ? }
          ? ? }
          }
          ?



          ?

          posted @ 2007-01-07 14:37 云自無心水自閑 閱讀(3490) | 評論 (1)編輯 收藏

          ?

          在Flex的開發過程中,尤其是在使用Cairngorm的時候,總會遇到需要在Model的屬性值改變后,需要調用一個指定的函數。傳統的解決方法是使用一個Setter方法,在這個方法中首先對屬性賦值,然后調用指定的函數,比如:

          ---------------------------
          [ChangeEvent("deleteEnabledChange")]
          public function get deleteEnabled() : Boolean {
          return _deleteButtonVisible;
          }

          public function set deleteEnabled(value : Boolean) : Void {
          _deleteButtonVisible = value;
          SimpleButton(deleteButton)._visible = false;
          dispatchEvent(new Event("deleteEnabledChange", this));
          }
          --------------

          但是現在我們有一個更簡潔的解決之道
          首先添加這樣一個類
          package com.adobe.ac.util
          {
          ?? public class Observe
          ?? {
          ????? public var handler : Function;
          ?
          ????? public function set source( source : * ) : void
          ????? {
          ???????? handler.call();
          ????? }
          ?? }
          }
          然后就可以使用這個作為標簽了。
          <util:Observe source="{ model.myProperty }"
          ????????????? handler="{ this.myFunction }"/>
          使用了這樣的一個標簽后,今后嘦是對model.myProperty進行賦值,就會調用myFunction
          這個號稱世上最小的標簽是不是很好用啊?

          posted @ 2007-01-07 02:15 云自無心水自閑 閱讀(1090) | 評論 (4)編輯 收藏

          現在我們將增加驗證、格式化和一些其他的功能。
          第四次迭代--添加功能
          現在我們回過頭來看那個單視圖的應用,增加一點真實性,我們模擬一下遠程服務有一點延時。我們在Delegate中使用flash.utils.setTimeOut來模擬延時。
          通常,當遠程服務在處理時,UI會展現一個進度條,禁用一部分控件,讓用戶明白不能再派發新的請求。在我們的例子中在遠程服務在處理的時候,我們會禁用“Get Quote”按鈕。完成這一點很容易,只需要在Model對象的StockQuote類中增加一個成員isPending,把它定義為一個bool形,這樣可以直接應用于綁定。

          ?

          [Bindable]
          public ?var?isPending?:?Boolean;

          ?

          增加驗證
          我們現在添加對股票報價的驗證功能,對于這一點,我們可以使用mx.validators.StringValidator來完成這一功能。應用中這兩個參數共同控制按鈕的有效性。這樣可以在Model對象中設置一個isValid屬性,用于組合這兩參數。

          private ?function?validate()?:? void
          {
          ????isValid?
          = ?(?isSymbolValid? && ? ! isPending?);
          }

          isSymbolValid是一個屬性,存放StringValidator的結果。
          在StockMarketPod.mxml中添加mx:StringValidator這個Tag

          < mx:StringValidator?
          ????
          minLength ="2" ?triggerEvent ="change" ?
          ????source
          ="{?symbolTextInput?}" ?property ="text"
          ????valid
          ="stockQuote.validateSymbol(?true?);" ?
          ????invalid
          ="stockQuote.validateSymbol(?false?);" />


          從視圖中直接調用Model對象不符合MVC原則,因為視圖原則上只能派發事件。但在這個例子中,這樣已經足夠好了。

          增加格式化
          我們將股票報價以金額的方式進行展示,在StockMarketPod.mxml中增加一個formatter

          < mx:CurrencyFormatter?
          ????
          id ="standardEuroFormatter" ??
          ????currencySymbol
          ="$" ?precision ="2" />
          將formatter的結果進行綁定
          < mx:Label? text ="{?standardEuroFormatter.format(?stockQuote.lastStockQuote?)?}" />


          現在看一下完整的StockQuote類

          package ?com.adobe.cairngorm.samples.dashboard.model
          {
          ????
          public ? class ?StockQuote
          ????
          {
          ????????[Bindable]
          ????????
          public ?var?lastStockQuote?:?Number;
          ????????[Bindable]
          ????????
          public ?var?isValid?:?Boolean;
          ????????[Bindable]
          ????????
          public ?var?statusMessage?:?String;
          ????????????????
          ????????
          private ?var?_isPending?:?Boolean;
          ????????
          private ?var?isSymbolValid?:?Boolean;
          ????????????????
          ????????[Bindable]
          ????????
          public ?function?get?isPending()?:?Boolean
          ????????
          {
          ????????????
          return ?_isPending;
          ????????}

          ????????
          ????????
          public ?function?set?isPending(?value?:?Boolean?)?:? void
          ????????
          {
          ????????????_isPending?
          = ?value;
          ????????????validate();
          ????????}

          ????????????
          ????????
          public ?function?validateSymbol(?isValid?:?Boolean?)?:? void
          ????????
          {
          ????????????isSymbolValid?
          = ?isValid;
          ????????????validate();
          ????????}

          ????????
          ????????
          private ?function?validate()?:? void
          ????????
          {
          ????????????isValid?
          = ?(?isSymbolValid? && ? ! isPending?);
          ????????}
          ????????
          ????}

          }

          其中isPending屬性的值由GetStockQuoteCommand控制

          private ?var?model?:?ModelLocator? = ?ModelLocator.getInstance();
          private ?var?stockQuote?:?StockQuote? = ?model.stockQuote;
          ?????????
          public ?function?execute(?event?:?CairngormEvent?)?:? void
          {
          ????stockQuote.isPending?
          = ? true ;
          ?????????????
          ????var?stockQuoteEvent?:?GetStockQuoteEvent?
          = ?GetStockQuoteEvent(?event?);??????????
          ????var?symbol?:?String?
          = ?stockQuoteEvent.symbol;
          ????var?delegate?:?StockMarketDelegate?
          = ? new ?StockMarketDelegate(? this ?);
          ????delegate.getQuoteForSymbol(?symbol?);????
          }

          ????????
          public ?function?onResult(?event?:? * ? = ? null ?)?:? void
          {
          ????
          // for?demo?purpose:?event?would?normally?be?an?event?object?of?remote?service?result.????????????
          ????stockQuote.lastStockQuote? = ?event?as?Number;????????????
          ????stockQuote.isPending?
          = ? false ;
          ????stockQuote.statusMessage?
          = ? "" ;
          }

          ????????
          public ?function?onFault(?event?:? * ? = ? null ?)?:? void
          {
          ????stockQuote.lastStockQuote?
          = ?NaN;
          ????stockQuote.statusMessage?
          = ? " Quote?retrieval?error. " ;
          ????stockQuote.isPending?
          = ? false ;
          }

          最后看一下StockMarketPod.mxml的全部代碼

          <? xml?version="1.0"?encoding="utf-8" ?>
          < mx:Panel?
          ????
          xmlns:mx ="http://www.adobe.com/2006/mxml"
          ????xmlns:util
          ="com.adobe.cairngorm.samples.dashboard.util.*" >
          ????????
          ????
          < mx:Script >
          ????????
          <![CDATA[
          ????????????import?com.adobe.cairngorm.control.CairngormEventDispatcher;
          ????????????import?com.adobe.cairngorm.samples.dashboard.model.StockQuote;
          ????????????import?com.adobe.cairngorm.samples.dashboard.events.GetStockQuoteEvent;????
          ????????????
          ????????????[Bindable]
          ????????????public?var?stockQuote?:?StockQuote;
          ????????????
          ????????????private?function?getQuoteForSymbol()?:?void
          ????????????{
          ????????????????var?event?:?GetStockQuoteEvent?=?new?GetStockQuoteEvent(?symbolTextInput.text?);
          ????????????????CairngormEventDispatcher.getInstance().dispatchEvent(?event?);
          ????????????}
          ????????
          ]]>
          ????
          </ mx:Script >
          ????
          ????
          < mx:CurrencyFormatter?
          ????????????????
          id ="standardEuroFormatter" ??
          ????????currencySymbol
          ="$" ?precision ="2" />
          ????????
          ????
          < mx:StringValidator?
          ????????
          minLength ="2" ?triggerEvent ="change" ?
          ????????source
          ="{?symbolTextInput?}" ?property ="text"
          ????????valid
          ="stockQuote.validateSymbol(?true?);" ?
          ????????invalid
          ="stockQuote.validateSymbol(?false?);" />
          ????
          ????
          < mx:Form >
          ????
          ????????
          < mx:FormItem? label ="Symbol" >
          ????????????
          < mx:TextInput?
          ????????????????
          id ="symbolTextInput" />
          ????????????
          < mx:Button?
          ????????????????
          label ="Get?Quote" ?
          ????????????????enabled
          ="{?stockQuote.isValid?}" ?
          ????????????????click
          ="getQuoteForSymbol();" />
          ????????
          </ mx:FormItem >
          ????????????????
          ????????
          < mx:FormItem? label ="Price?Quote" >
          ????????????
          < mx:Label? text ="{?standardEuroFormatter.format(?stockQuote.lastStockQuote?)?}" />
          ????????????
          < mx:Label? text ="{?stockQuote.statusMessage?}" />
          ????????
          </ mx:FormItem >
          ????????
          ????
          </ mx:Form > ????
          </ mx:Panel >


          此視圖中我們不需要使用ModelLocator,而是使用StockQuote作為參數傳入StockMarketPod.mxml
          引用視圖的代碼

          < mx:Script >
          ????
          <![CDATA[
          ????????import?com.adobe.cairngorm.samples.dashboard.model.ModelLocator;
          ????????import?com.adobe.cairngorm.samples.dashboard.model.StockQuote;
          ????????????????????????????????????
          ????????[Bindable]
          ????????private?var?model?:?ModelLocator?=?ModelLocator.getInstance();
          ????????[Bindable]
          ????????private?var?stockQuote?:?StockQuote?=?model.stockQuote;????
          ????
          ]]>
          </ mx:Script >
          ?
          < view:StockMarketPod?
          ????
          stockQuote ="{?stockQuote?}" ?
          ????title
          ="Stockmarket?Pod" />

          ?

          只傳遞需要的信息給視圖是一個比較好的做法,而盡量少使用ModelLocator這樣的全局變量,這樣也使用視圖重用性更高。

          posted @ 2006-12-29 00:36 云自無心水自閑 閱讀(914) | 評論 (0)編輯 收藏

          上次介紹了如何在業務邏輯中改變視圖,這次講解一種新方法。我們的股票市場顯示圖將擴展為多股票報價查詢器。我們將看到業務邏輯是怎么調整每個視圖的。而且我們還會接觸到無狀態命令是怎么使得事情變得簡單。
          第三次迭代--創建業務邏輯管理多視圖
          我們經常可以發現會有很多個類型一樣的視圖,其背后的功能也非常類似。每個視圖顯示一個Model對象。這些視圖可以在開始時從管理對象處請求一個Model對象。比如:我們的StockMarketDashboard.mxml可以進行這樣的添加:

          < view:StockMarketPod?
          ????
          quoteId ="quote1" ?
          ????title
          ="Stockmarket?first?pod" />
          < view:StockMarketPod?
          ????
          quoteId ="quote2" ?
          ????title
          ="Stockmarket?second?pod" />
          < view:StockMarketPod?
          ????
          quoteId ="quote3" ?
          ????title
          ="Stockmarket?third?pod" />
          < view:StockMarketPod?
          ????
          quoteId ="quote4" ?
          ????title
          ="Stockmarket?fourth?pod" />

          注意:視圖需要傳遞一些唯一的標識,我們將這些標識添加到StockQuote類。

          package ?org.nevis.cairngorm.samples.dashboard.model
          {
          ????
          public ? class ?StockQuote
          ????
          {
          ????????[Bindable]
          ????????
          public ?var?lastStockQuote?:?Number;
          ????????[Bindable]
          ????????
          public ?var?stockQuoteError?:?String;????????
          ????}

          }


          管理對象StockQuoteManager,在ModelLocator實例中初始化。但是StockQuoteManager會是一個怎樣的對象呢?
          通常我使用Hashmap來實現,其鍵值就是視圖中的唯一標識符。在構造函數中我們可以初始化這個Hashmap,Flex2中我們使用flash.utils.Dictionary

          public ?function?StockQuoteManager()?
          {
          ????stockQuotes?
          = ? new ?Dictionary();
          }


          getStockQuote方法返回一個stockQuote對象

          public ?function?getStockQuote(?quoteId?:?String?)?:?StockQuote
          {
          ????var?key?:?String?
          = ?quoteId;
          ????
          if (?stockQuotes[?key?]? == ? null ?)
          ????
          {
          ????????var?stockQuote?:?StockQuote?
          = ? new ?StockQuote();
          ????????stockQuotes[?key?]?
          = ?stockQuote;
          ????}

          ????
          return ?StockQuote(?stockQuotes[?key?]?);
          }


          StockMarketPod.mxml幾乎沒有什么改動。只需要將那個唯一的標識符發送給命令,因為命令需要從管理對象處取得StockQuote對象。所以GetStockQuoteEvent類多了一個quoteId屬性。
          在GetStockQuoteCommand中,需要將唯一標識符保存在一個成員變量中

          private ?var?model?:?ModelLocator? = ?ModelLocator.getInstance();
          private ?var?quoteId?:?String;
          ?????????
          public ?function?execute(?event?:?CairngormEvent?)?:? void
          {
          ????var?stockQuoteEvent?:?GetStockQuoteEvent?
          = ?GetStockQuoteEvent(?event?);?????????????
          ????var?symbol?:?String?
          = ?stockQuoteEvent.symbol;
          ????quoteId?
          = ?stockQuoteEvent.quoteId;
          ????var?delegate?:?StockMarketDelegate?
          = ? new ?StockMarketDelegate(? this ?);
          ????delegate.getQuoteForSymbol(?symbol?);
          }

          ????????
          public ?function?onResult(?event?:?ResultEvent? = ? null ?)?:? void
          {
          ????
          // simulate?a?result?from?service
          ????var?lastStockQuote?:?Number? = ?Math.random()? * ? 50 ? + ? 5 ;
          ????var?stockQuote?:?StockQuote?
          = ?model.stockQuoteManager.getStockQuote(?quoteId?);
          ????stockQuote.lastStockQuote?
          = ?lastStockQuote;
          ????stockQuote.stockQuoteError?
          = ? "" ;
          }

          ????????
          public ?function?onFault(?event?:?FaultEvent? = ? null ?)?:? void
          {
          ????var?stockQuote?:?StockQuote?
          = ?model.stockQuoteManager.getStockQuote(?quoteId?);
          ????stockQuote.lastStockQuote?
          = ?NaN;
          ????stockQuote.stockQuoteError?
          = ? " An?error?occured. " ;
          }

          注意一下,在上面的代碼中我們使用的是無狀態命令,在Cairngorm的說明中,無狀態命令是每次Cairngorm事件的響應都創建一個新的命令實例的方式。因此,在這種方式中我們可以放心地把變量存儲在成員變量中,而不用擔心被其他人改變。

          posted @ 2006-12-28 00:50 云自無心水自閑 閱讀(714) | 評論 (0)編輯 收藏

          當服務端或者客戶端的邏輯變化后,有很多種方法來更新視圖。我比較推薦使用ModelLocator策略,主要是使用Flex的綁定功能。
          通常你的視圖與ModelLocator的屬性綁定,這些屬性可以由命令或者其他的業務邏輯或者其他視圖所改變。而一旦這些屬性發生了變化,所有與它們綁定的視圖都隨之變化。
          因為很多的Cairngorm的例子都想做得淺顯易懂,因此經常是簡單地將這些屬性做為ModelLocator中的一個暴露給外界的成員變量。而當Cairngorm的應用變得龐大的時候,這往往是不夠的。在此我將會專門針對這個問題展示一個例子。這個例子是一個股票市場的顯示表。
          第一次迭代:將應用運轉起來
          首先看一下Cairngorm所主張的MVC模式。目前股票市場顯示表將只包含一些簡單的UI控制。點擊“GetQuote”來派發Cairngorm事件,調用命令來請求一個新報價。StockMarketPod.mxml中在Button的Click事件中派發Cairngorm事件。

          < mx:Button? label ="Get?Quote" ?click ="getQuoteForSymbol();" />

          相應的腳本代碼:

          ?
          import?org.nevis.cairngorm.samples.dashboard.events.GetStockQuoteEvent;????????????????????????????????????
          private?function?getQuoteForSymbol()?:?void
          {
          ????var?event?:?GetStockQuoteEvent?
          =?new?GetStockQuoteEvent(?symbolTextInput.text?);
          ????dispatchEvent(?event?);
          }

          GetStockQuoteCommand響應并處理這個Cairngorm事件,請求一個業務代理類來報價。

          public?function?execute(?event?:?CairngormEvent?)?:?void
          {
          ????var?symbol?:?String?
          =?GetStockQuoteEvent(?event?).symbol;
          ????var?delegate?:?StockMarketDelegate?
          =?new?StockMarketDelegate(?this?);
          ????delegate.getQuoteForSymbol(?symbol?);
          }


          在實際情況中,需要進行一個遠程的服務器端的調用,在Demo中,為簡化起見,我注釋掉了遠程調用的相關代碼。這里StockMarketDelegate.as只是對命令進行回調。

          public?function?StockMarketDelegate(?responder?:?Responder?)
          {
          ????
          //disabled?for?demo
          ????
          //this.service?=?ServiceLocator.getInstance().getService(?"stockMarketDelegate"?);
          ????this.responder?=?responder;
          }

          ????????
          public?function?getQuoteForSymbol(?symbol?:?String?)?:?void
          {
          ????
          //disabled?for?demo
          ????
          //var?call?:?AsyncToken?=?service.getQuoteForSymbol(?symbol?);
          ????
          //call.resultHandler?=?responder.onResult;
          ????
          //call.faultHandler?=?responder.onFault;
          ????if(?symbol?==?"fail"?)
          ????
          {
          ????????responder.onFault();
          ????}

          ????
          else
          ????
          {
          ????????responder.onResult();
          ????}

          }

          我們的StockMarketPod視圖只需要兩條消息,
          1. 股票的報價
          2. 錯誤消息
          因為現在是第一次迭代過程中,處理比較簡單,因此使用ModelLocator的成員來解決。

          public?var?lastStockQuote?:?Number;
          public?var?stockQuoteError?:?String;


          在此Demo中,GetStockQuoteCommand命令模擬返回相應的結果。

          public?function?onResult(?event?:?ResultEvent?=?null?)?:?void
          {
          ????
          //simulate?a?result?from?service
          ????var?stockQuote?:?Number?=?Math.random()?*?50?+?5;
          ????model.lastStockQuote?
          =?stockQuote;
          ????model.stockQuoteError?
          =?"";
          ?}

          ????????
          public?function?onFault(?event?:?FaultEvent?=?null?)?:?void
          {
          ????model.lastStockQuote?
          =?NaN;
          ????model.stockQuoteError?
          =?"An?error?occured.";
          }

          StockMarketPod視圖綁定這些成員并進行一些格式化的處理。

          <mx:FormItem?label="Symbol">
          ????
          <mx:Label?text="{?formatQuote(?model.lastStockQuote?)?}"/>
          </mx:FormItem>
          <mx:FormItem>
          ????
          <mx:Label?text="{?model.stockQuoteError?}"/>
          </mx:FormItem>

          格式化函數的腳本

          private?function?formatQuote(?quote?:?Number?)?:?String
          {
          ????
          return?(?isNaN(?quote?)?)???""?:?String(?quote?);
          }


          現在我們來進行重構并將一些功能從視圖中抽取出來到一個可以進行單元測試的工具類中。

          第二次迭代,創建符合需求的業務邏輯
          現在我們已經有一個可以運行的最簡單的應用。當你的應用變得龐大后,將會有很多的限制。你會發現你的ModelLocator非常的臃腫,以致于有時候,你都找不到你所要的成員。甚至會有命名沖突的事情發生。
          一個普通的重構方法是封裝你的用例圖中的成員成為一個業務對象。這個業務對象能夠表達業務上下文中需要的視圖信息。你可以把業務對象設計得最適合用例圖的粒度。在一個大型的應用中,你可能會設計一系列的業務對象來表達你的用例。你的視圖將會綁定這些對象或者這些對象的屬性上。通過這種方法,ModelLocator與其目標之間的聯系更容易,開發者更容易掌握業務邏輯所包含的內容。
          在這個Demo中,我們可以把astStockQuote和stockQuoteError這兩個成員封裝到一個業務對象中。

          package?org.nevis.cairngorm.samples.dashboard.model
          {
          ????
          public?class?StockQuote
          ????
          {
          ????????[Bindable]
          ????????
          public?var?lastStockQuote?:?Number;
          ????????[Bindable]
          ????????
          public?var?stockQuoteError?:?String;
          ????}

          }


          這樣在ModelLocator中,我們只需要定義一個成員
          public var stockQuote : StockQuote = new StockQuote ();
          我們的視圖也相應修改為:

          <mx:FormItem?label="Symbol">
          ????
          <mx:Label?text="{?formatQuote(?model.stockQuote.lastStockQuote?)?}"/>
          </mx:FormItem>
          <mx:FormItem>
          ????
          <mx:Label?text="{?model.stockQuote.stockQuoteError?}"/>
          </mx:FormItem>

          posted @ 2006-12-27 01:31 云自無心水自閑 閱讀(1795) | 評論 (0)編輯 收藏

          1、www.FlashDevelop.com網站最近發布了FlashDevelop2.0.2,其中增加了對Flex2的支持。
          2、下面介紹一下使用的方法。我用的是一個筆記本,只有一個C盤,所有安裝路徑都在C盤。
          3、首先是下載FlashDevelop2.0.2(以下簡稱FD),我安裝在c:\program files\flashdevelop目錄下。
          還要注意下載安裝JDK5,和.net framework1.1(這個程序是用C#開發的)
          4、再下載Flex2 SDK,從www.flex.org的左上角可以找到,好象要在Adobe公司里注冊一下。
          下載完畢后,解壓縮,我是放在c:\flex_2_sdk目錄下。
          ? 運行FD,按F9進入程序設置,找到ASCompletion.Flex2SDK.Path這個選項,把它的值設為SDK的路徑。
          我這里就是C:\Flex_2_SDK
          5、下載AS3 Intrinsic Classes URL Address我把它解壓縮在C:\Program Files\FlashDevelop\Library目錄下
          6、下載
          AS3 top-level declaration解壓縮在C:\Program Files\FlashDevelop
          在FD中的程序設置(Program Setting)中設置
          ASCompletion.Macromedia.Classpath的值為此路徑,
          設置
          ASCompletion.MTASC.UseStdClasses的值為False
          7、下載
          the MXML definition file這解壓縮在C:\Program Files\FlashDevelop\Data目錄下

          到此步驟,FD的安裝基本告一段落。

          下面就可以新建項目了,為方便起見
          8、下載項目模板 http://www.bit-101.com/flashdevelop/ProjectTemplates.zip,解壓縮到C:\Program Files\FlashDevelop\Data\ProjectTemplates目錄下。
          9、重新啟動FD,新建項目,選擇Flex模板。在右邊會看到deploy、html_template, src三個目錄和build.properties, build.xml兩個文件,src目錄下有一個app.mxml的空文件。
          至此,項目的目錄框架搭建完成。下面就是要編譯生成SWF文件了。

          10、對于編譯生成SWF文件有好幾種方式,在此介紹兩種,一種是FD開發者提供了,使用MSASC,一種是使用Ant。第一種速度奇塊,但是設置比較復雜,第二種速度較慢,比較方便。
          11、如果使用第一種,就需要在每個文件的頭部添加東西
          AS文件頭添加
          /**
          * @mxmlc -default-size 400 300 -incremental=true
          */
          mxml文件頭添加
          <!-- @mxmlc -default-size 400 300 -incremental=true -->
          12、如果是用第二種方法,首先要裝Ant,這個大家可能都有。
          13、然后修改Build.properties文件,把里面的一些路徑改一下。比如:flex2.dir
          14、然后到C:\Program Files\FlashDevelop\Settings目錄下找到Toolbar.xml
          添加一行
          <button label="ANT Build" click="PluginCommand" image="54" tag="Run;SaveAll;ant" shortcut="F7" />
          15、重新啟動FD,在工具條上看見多了一個圖標,直接點這個按鈕,或者按F7,就可以調用Ant生成SWF文件了。而且Swf文件的顯示就是在FD集成環境里面的。第一種方式是在外部啟動一個IE顯示Swf的。

          posted @ 2006-12-23 02:42 云自無心水自閑 閱讀(5192) | 評論 (0)編輯 收藏

          現在最新的版本是2.02, 主頁: http://www.ariaware.com
          ?
          結構框架圖:



          images\ebx_144215778.jpg

          看得出: 這個框架與Cairngorm非常的相似, 但是進行了相當的簡化.

          Controller + Command + ServiceLocator 這三駕馬車還在.
          Cairngrom中的Model, EventDispatcher, Delegate都不存在了.
          ViewHelper和ViewLocator被ArpForm所取代.
          對于初學者來說,這個簡化版的可能更容易被接受吧.

          posted @ 2006-12-16 02:02 云自無心水自閑 閱讀(1184) | 評論 (0)編輯 收藏

          僅列出標題
          共29頁: First 上一頁 20 21 22 23 24 25 26 27 28 下一頁 Last 
          主站蜘蛛池模板: 常德市| 克拉玛依市| 台州市| 纳雍县| 麦盖提县| 呼和浩特市| 临潭县| 胶州市| 石家庄市| 古丈县| 绥芬河市| 沿河| 上思县| 剑川县| 平山县| 兴化市| 桃园市| 灵寿县| 马山县| 松江区| 东明县| 宜黄县| 包头市| 中宁县| 桐梓县| 石城县| 京山县| 龙里县| 永新县| 兴宁市| 海口市| 张家口市| 滨州市| 昔阳县| 西和县| 阿拉善左旗| 武隆县| 临高县| 确山县| 九龙坡区| 双柏县|