Skip to main content

Posts

Showing posts from 2009

[AS3] Data Binding in AS3 project

使用 Flex 開發過一陣子後,對於 [Bindable] 這個懶人 tag 有說不出的喜愛,然而在 Flash 中利用 Proxy 其實也可以達到相同的功用...但是 Flex SDK 免費擺在那邊不好好使用太對不起自己了... 在參考了 Ticore's Flex 2 Bindable Metadata Tag 背後實際作用 ( Ticore 萬歲!!),其實只需要將 Flex SDK frameworks/libs/framework.swc 包加到 Flash library 下,就可以使用 Flex 的 Binding 機制來達到綁定。前提是提供綁定的 host 屬性需要有 [Bindable] 才有作用,所以下面範例無法直接將 txt.text 與 txt1.text 綁定,需要透過 [Bindable] string:String 來做中介。 以下使用 FlashDevelop or Flex Builder 來編寫: package { import flash.display.Sprite; import flash.events.Event; import flash.text.TextField; import mx.binding.utils.BindingUtils; [SWF(width='400', height='300', backgroundColor='#ffffff', frameRate='30')] public class TestBindable extends Sprite { public var input:TextField; [Bindable] public var string:String = ""; public function TestBindable() { if( stage ){ init(); }else { addEventListener( Event.ADDED_TO_STAGE , init ); } } private function init(event:Event = null):void{

[Flex] 3.4 SDK HttpService responder bug

Reference: http://twitter.com/sectore/status/3605078853 本篇用來筆記用, 在使用 Flex 3.4 SDK 的時候如果你有使用到 HttpService 利用 Responder 置入 result and fault function 時,你應該會發現 result 會被 call 兩次。 參考 Jens Krause「推」上的解法: public function callService():void { // call the service service=new HTTPService(); service.url=yourUrl; var token:AsyncToken=service.send(); token.addResponder(new Responder( result, fault)); //重點是這句 service.addEventListener( ResultEvent.RESULT , emptyResult ); } public function emptyResult(e:Event):void{} 這樣就可以解掉囉~~

經濟部水利署發表以 Adobe Flex Builder 建立的新系統

[水文水資源資料管理供應系統] 以下是其公關稿節錄: 讓水文水資源資料管理供應系統更加專業便捷 【2009 年 9 月 22 日,台北訊】全球軟體大廠奧多比今日宣布再添一 Adobe® Flash® 平台技術應用佳績!以提供技術服務、軟體工程、應用服務為主的地理資訊系統整合商銳俤科技,成功協助經濟部水利署「水文水資源資料管理供應系統」(http://gweb.wra.gov.tw/wrweb/) 的開發與升級,使其更具互動便利性。銳俤科技以 Adobe Flex® Builder™ 3 將現有複雜的水資源統計資料與空間數據轉化為可隨點即查的豐富型媒體系統,建立人性親和的系統介面。 ~ more... 裡面使用 Flex 製作的是「地理資訊」選項,用 Safari 4.0.3 + OSX 10.5.8 看的時候會有 Button 被遮蔽的問題等於是無法使用,這個 bug 是比較神奇一些...也蠻有可能是一開始的 UserProxy Error Response 導致...FireFox debug flash player 有捕捉到錯誤‧ 最近 Erin 的主力都是在做 Flex 相關開發,當然樂見在台灣有越來越多的使用案例上市!!Flex 加油! =)

[Flex] flexstore 的 find 功能補完

關於 Adobe flexstore 這個範例應該對學習過 Flex 的人是無人不知無人不曉,剛好有人問我如何將範例中的 Products / Find 功能補上,以下就是一個簡單改法: 1. 修改 samples.flexstore.ProductFilter.as 先加入一個公開屬性 searchText:String public var searchText:String; 補上 find function public function find(product:Product):Boolean { var str:RegExp=new RegExp(searchText, "i"); return (searchText == "") ? true : (str.test(String(product.name))) || (str.test(String(product.price))) || (str.test(String(product.series))) || (str.test(product.description)) || (str.test(product.highlight1)) || (str.test(product.highlight2)) || (str.test( "Tri-band" )) || (str.test("Camera")) || (str.test("Video")); } 2. 修改 ProductFilterPanel.mxml 加入 callFind event function private function callFind(event:Event):void{ var filter:ProductFilter = new ProductFilter(); filter.searchText = searchText.text; var e:ProductFilterEvent = new

[AS3] pureMVC Utility - WidgetsConsole 1.0.0

Project Name: pureMVC Utility - WidgetsConsole Version: 1.0.0 Project Owner: Erin Lin Description: An utility is under pureMVC Multicore that has Flex only and AS3 two versions. Demo: WidgetsConsole Live Demo with source code Demo source code Download: WidgetsConsole Open Source Project Home pureMVC website: http://puremvc.org/ 沒想到我第一個 google code open source project 就獻給 pureMVC 了... 套用 pureMVC 到 Flex 專案第一個遇到的問題就是 view components 的控制,Flex 專案的 view 總類太多:有 Modules, UIComponent, external swf and pop-up view...etc. 整個專案作下來光 view 就可能換上幾十個頁面,先前分享了運用 StateMachine 來處理 view 的轉換,中大型專案作下來 code 的複雜度也是非常可觀。我在今年二月分享了 [Flex] pureMVC MultiCore with Modules 就開始著手將其概念包裝成 pureMVC 的工具包,使用到目前為止整個架構還是挺完善,所以在這邊與大家分享。 WdigetConsole 顧名思義是「 相同目的 views 組合 = Widget 」 的中央控制中心,將程式內加入 WidgetsConsole 的 widget 統一控管,最終只需要 sendNotification 就可以達到 view 的新增跟刪除(因為我是懶人工具的愛好者,懶人工具的定義就是以最低的限度達到所需要的效果,所以這個工具包的自由度很高!) 以下是簡單講解 WidgetsConsole 是什麼: Widget 的定義: View component(s) + WidgetMediator + WidgetCommand 實作的 WidgetCommand:

[pureMVC] Flex app 開發的心得分享

使用 pureMVC 開發到現在,也遇到不少網友詢問相關問題,以下是 Erin 整理的幾個使用 pureMVC framework 開發 Flex app 的心得分享: 雖然 pureMVC Standard 版本就很夠用了,但是你的 app 有未知擴充需求的話還是建議使用 Mulitcore 版本以達最大的開發彈性。 先問問自己能不能理解架構內 Notification and Command 是什麼作用?如果答案是『NO』,請先熟悉 pureMVC 的架構再行考量是不是要實作...因為有太多問題都可以利用它們解決。 先搞清楚你將要開發的 app 流程,花點時間研究官網上的 pureMVC Utilities,一定有工具包可以解決你的需求。 除了 Application 外 view component 不應該持有任何跟 pureMVC 有關的 Class instance reference,請善用 Flex & Flash Event 機制與外部溝通。 別把 view component 直接對 view component 溝通的開發邏輯帶到架構內,如果你還是打算這樣作就根本不需要使用任何 framework 來幫助開發! View componet 溝通邏輯應該是 A-view component -> Event -> A-Mediator -> Notification -> Proxy, Command or B-Mediator -> B-view component。Event 機制在這邊有很大的作用,Mediator "儘量"不持有 view componet 子物件只接收其 Event ,不僅可以讓你跳脫如何用 A view 控制 B view 的思維...因為 A view 根本不需要去知道它發了 Event 後誰會被控制; 對 view component 新增修改也比較容易,ex. view component 由 Flex 3 改 Flex 4 版本(尤其 Flex 4 的架構改很大...你就會發現用 Event 的重要性...) Mediator 要 override onRegister and onRemove function,做人要有始有終,請記得 EventL

[AS3] 簡單講客製 Event (2)

一般的使用只需要繼承自 flash.events.Event, 並且覆寫 clone 這個 function package events { import flash.events.Event; public class CustomEvent extends Event { public var data:Object; // 喜歡什麼都可以自己加~~當然也可以用 getter & setter 宣告 public function CustomEvent( type:String , data:Object ) { super(type); this.data = data; } override public function clone():Event { return new CustomEvent( type , data ); } } } 如果你的 Event 需要 bubbles 請修改: super( type , true ) 方便 debug 版本,就是多一個覆寫 toString function package events { import flash.events.Event; public class Custom2Event extends Event { public var output:String; public static const UPDATE_OUTPUT:String = "update_output"; public function Custom2Event( type:String , output:String) { super(type); this.output = output; } override public function clone():Event { return new Custom2Event( type , output ); } override public function toString():String { //印出你想要看的資訊 return formatToString("Custom2Event"

[Flex] pureMVC and Utility-StateMachine (2)

Reference: PureMVC AS3 Utility - StateMachine 補充講解一下 StateMachine 是怎樣運作的。 public class StateMachine extends Mediator 打開它的原始碼就可以清楚看到它是一個 Mediator,其實整個機制就是像轉接器,收到 StateMachine.ACTION 通知後,就自動轉到對應的 State 然後利用 sendNotification(); 將新的通知轉發出去,所以它統一的 Notification 寫法就是: sendNotification( StateMachine.ACTION , data , "Your_State_Action_String" ); 然後它就會轉發 sendNotification( "Your_State_Exiting/Entering/Changed_String" , data ); 在 InjectFSMCommand.as 內使用 XML 來宣告 State <state name="Your_State" exiting="Exiting_Notification_Name" entering="Entering_Notification_Name" changed="Changed_Notification_Name"></state> 用法跟一般 Command or Mediator 處理 Notifications 一樣,將 exiting , entering , changed 狀態分別註冊到 Command 又或者直接在 Mediator 內處理通知。

[Flex] pureMVC and Utility - StateMachine

目前手上的 Flex 專案幾乎都是使用 pureMVC 的架構來開發,用到現在還是沒有發現什麼大的缺點,嚴格說起來還挺好用的。組合好心人分享的 pureMVC 工具包也相當好玩。除了自己寫的工具外,目前最愛用的便是 Neil Manuell (project owner) 所分享的 Utility - AS3 StateMachine ,小型專案只需要配合這個就非常完美了~~ 在 Application 的 MXML 中使用 ViewStack 來控制場景變換,是很直覺的作法。但如果你專案還有擴充的空間,這樣做場景到最後你一定後悔!因為可能不是每個 View 都會被新增到 同一個地方。以下是一個簡單的範例講解 pureMVC + StateMachine 的應用。 範例的 Classes tree 開始前請先下載以下的 library:為了方便開發,統一使用 multicore 版本 PureMVC MultiCore for AS3 Utility - AS3 StateMachine 使用 swc 的話請直接將 .swc 檔放置到 libs/ 內,如果是下載 class 的話,請放置到 src/ 中 範例場景說明: Application MXML 中有個 tab bar 點選後會換場景 Shop <-> Shop1 ( 當然場景可以無限新增,這只是個範例...) pureMVCAndStateMachine.mxml <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()" layout="vertical"> <mx:Script> <![CDATA[ import mx.events.ItemClickEvent; import com.mvc.ApplicationFacade; private function init():void{ ApplicationFacade

[ AS3] 簡單講客製 Event

很多人從 AS2 轉 AS3 後,還是習慣照用 MovieClip(root) 之類的寫法,但其實 AS3 的 Event 機制提供了一個良好的環境讓你脫離兒子物件直接控制老爸物件 (如同 MovieClip 中寫 _root.去做啥())。這就是工程師最愛講的:loose coupling (鬆耦) 在 AS3 中,所有的 DisplayObject 都繼承自 EventDispatcher,所以它們可以收聽跟發送 Event。 以下是一個簡單的範例講解客製 AS3 Event 應用... 情況解說:主stage a.swf 載入 b.swf ,當點選 b.swf 內的按鈕須要通知 a.swf gotoAndPlay("labelA")。如果你沿用 AS2 寫作邏輯,你一定會在 b.swf 內的按鈕寫上: btn.addEventListener( MouseEvent.CLICK , onClick ); function onClick(e:Event):void{ // 不管怎樣就是只能控制 [MainTimeline] 去 gotoAndStop("labelA") MovieClip( parent.root ).gotoAndStop("labelA"); } 又或者將控制動作寫在 a.swf 內: var ldr:Loader = new Loader; ldr.contentLoaderInfo.addEventListener( Event.COMPLETE , onLoaded ); ldr.load( new URLRequest ( "b.swf" ) ); function onLoaded(e:Event):void{ var mc:MovieClip = ldr.content as MovieClip; addChild(mc); //喔喔將 b.swf 的 btn 一併綁進來了喔!所以按鈕絕對不能亂改名喔,也不能改階層 mc.btn.addEventListener( Event.CLICK , onClick); } function onClick(e:Event):void{ gotoAnd

[543] 最近的 Erin 在做什麼?

最近 Erin 噗浪玩很大,都忘了要寫 blog... 自從四月初開始認真當 SOHO 後,每天都過著"醉生夢死"的生活...?? 目前的行程: 五六月 - 滿檔中... 七月( 每週一三晚間 ) - 授課 飛肯 ActionScript 3.0 & XML 資料庫整合應用班 (會準備什麼隱藏課程?你來了就知道...XD ) 七八九月 - 短期約聘面談中 十月 - 等你聯絡囉~~^^ 近期如果你有"不急的" Flex / AIR / Flash / Flash lite 相關的案子需要外發都可以直接與我聯絡!也接受短期約聘喔! 1 ) 如何聯絡 Erin? 寄 e-mail 是最快的喔!不然可以透過 blog 上的 Plugoo 視窗與我聯絡,再來就是噗浪...XD E-mail: erinylin [at] gmail [dot] com Plurk: http://www.plurk.com/erinlin 2 ) 為什麼不公開留 MSN...?? 嗯...因為 Erin 記憶不好,外加 MSN 一堆幾百年沒有聯絡的朋友名單...所以還是先透過 e-mail 聯絡一下再加入比較記得... 3 ) Erin 到底會什麼? 啊...這個問題就有點難回答了,Erin 古早以前是個美術設計師,也當過電腦兼職講師,後來轉職當互動工程師,現在主要是做 AS1/AS2/AS3 "都可以"的前端互動開發(程式為主)。凡舉 Flex / AIR / Flash / Flash lite 相關的案子都做過,整合過很多專案,動畫也製作過(人物設定+動畫製作),在手機產業界接觸了 UI 設計與 UE 研究,最近經手的案子有國外活動網站(AS3+pv3D)中文化,公司進銷存系統網路化(Flex)...所以 Erin 到底能做什麼?嗯...就等你來研究囉~~ 4 ) 為什麼沒有作品集可以看? 這個就要問問為什麼一堆公司都要你簽 NDA (保密協定) ,搞的 Erin 也懶得公開經手過的作品,所以想要看到 Erin 做過什麼,就請記得找 Erin 面談時要註明『請帶電腦』這四個字 =) 裏 1 ) 目前 Erin 缺什麼? 嗯...缺男人(咦?這才是這篇的重點嗎?)

[Flex] Button enabled=false 自動灰階

嗯...這只是一個懶人小技巧,為了就是省下作 Button enaqbled=false 時的灰階 Icon 圖...( 這個作法是將 disable 狀態直接都變成灰階的...所以設 disable 文字顏色也沒用喔...XD ) 原理蠻簡單的就是 override 掉 updateDisplayList 這個 function ( override enabled setter 也可行) /* LazyButton Copyright (c) 2009 Erin Lin ( Yu-Shan Lin) Your reuse is governed by the Creative Commons Attribution 3.0 License 最近大家都很愛寫CC license 所以我也來寫一下...XD enabled = false; 變灰階 */ package { import mx.controls.Button; import flash.filters.ColorMatrixFilter; public class LazyButton extends Button { public function LazyButton() { super(); } override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); if(!enabled){ filters = [new ColorMatrixFilter( [0.3086,0.6094,0.0820,0,0, 0.3086,0.6094,0.0820,0,0, 0.3086,0.6094,0.0820,0,0, 0,0,0,1,0])]; }else{ filters = []; } } } }

[Flex] pureMVC MultiCore with Modules

跟 pureMVC MultiCore & Modules 相處幾天後發現了一個簡易串接流程能互相接聽與發送訊息(其實還有更爛的方法...XD 只是為了能自動化改用這個...)。不能說下面分享的是很好的解法,只能說它應該是個蠻容易理解外加還沒發現有啥嚴重 bug 的方法... 做法其實很簡單,就是 System facade 在 load Module 時,建立一個 Module 專用的 Mediator 並且將 Module 指定給它為其 viewComponent,就可以透過這個 Mediator 串接起來,這樣不管有多少個 Modules 都可以對應一個 ModuleMediator 來處理。這個串接的 Mediator 特別的地方就是它做了雙向註冊,如同轉接國際電話的接線生,因為跟兩邊都有關係,所以可以接聽跟發送兩邊的 Notifications。 請看 Live Demo (Demo 頁點選滑鼠右鍵可以看 source code ) ModuleManager 是寫在 Main.mxml 內而不是跟著 ModuleCommand 一起,原因是在 Flex 3.2 SDK 之後版本為了解掉更嚴重的 Module load & unload memory leak bug.. IModuleInfo 是區域變數的話,就容易被 GC 掉...這不是個 bug 喔!(Adobe 講的...也不知道是真的假的...沒特別研究...) Module 沒有真正 unload 掉,反正它會反覆載入,就不真的移除了...所以請自助... System facade 只用 ModuleCommand and ModuleMediator 處理所有的外部 Modules,所以重點都在這兩個 class 內...XD 為了輸出專案時不會將 Module 一併打包和要統一命名 Module's facade,所以外部的 Module 都需要 implements IModuleComponent interface。 (Edit: 3/4/2009) 由於 System facade 掌握著 Module facade 的名字,如果 System message 需要傳到特定的 Module 也可以很簡單的實現...=P

[Flex] Custom TweenEffect with Pixel Bender Filter

續前篇。 如果每一次 apply pixel bender 到轉場 effect 都要寫一長串的話實在有點堅強過頭... 要符合懶人精神將常用的 pixel bender filter 效果實作成 TweenEffect 才是明智的選擇。參考了 Flex help 與其他 TweenEffects,以下是簡單客製 TweenEffect 並加上 pixel bender filter 的作法: 每一組 TweenEffect 都由兩個 class 組成: TweenEffectInstance 與 TweenEffect ; 各自有幾個重點 functuon 需要被 override。別忘了先將上篇提到的 CrystallizeShader.as 放到 effects/ 下。 1. 製作 effects/CrystalEffectInstance.as:( 顧名思義就是被作用的實體 ) package effects { import flash.display.Shader; import flash.filters.ShaderFilter; import mx.effects.Tween; import mx.effects.effectClasses.TweenEffectInstance; public class CrystalEffectInstance extends TweenEffectInstance { public var sizeTo:Number; public var sizeFrom:Number; private var shader:CrystallizeShader = CrystallizeShader.getInstance(); public function CrystalEffectInstance(target:Object) { super(target); } // Override play() method class. override public function play():void { // 一定要有 super.play(). super.play(); size

[Flex] Pixel Bender Filter 動畫應用

雖然 Pixel Bender 已經出現了好一段時間,但是一直都沒很認真的看過,周遭朋友也鮮少討論它...直到最近工作需求才有開始使用。以下是集合各家長處能簡單應用 Pixel Bender Filters 到 AS3 的作法。 先到 Adobe Pixel Bender Exchange 挑選想要的特效 (這邊是選擇 Crystallize ) ,下載後解壓出 Crystallize.pbj 曾經從 CJ Cat 那邊聽到 pbj 可以整個轉換到 AS 內,經過 google 大神指點,找到了一個超級無敵好用的 PBJ to AS converter... 感謝作者 Marek Burn 的好心分享!!!! 利用 converter 轉換 pbj to AS, 存成 CrystallizeShader.as 放到工作目錄內。Pbj 內可設定參數可以參考轉出來的 as 檔內說明。 編寫 mxml: 使用 mx 包內建的 Tween <?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init()" layout="horizontal" > <mx:Script> <![CDATA[ import mx.effects.Tween; private var shader:CrystallizeShader; private function init():void{ var initNum:Number = 50; shader = CrystallizeShader.getInstance(); shader.size = initNum; var tween:Tween = new Tween(this, initNum, 1, 6000, -1, onUpdate, onEnd ); w1.filters = [ new ShaderFilter(shader)

[Flex] Cairngorm v.s. pureMVC

跟 Cairngorm and pureMVC 相處過一陣子之後,在這邊與大家分享一下使用它們在 Flex 中的開發經驗(也許有錯誤的理解,請多指正囉!) Cairngorm : 喜歡的部份: 架在 Flex framework 上使用中央 Event (CairngormEventDispatcher )機制,UI 開發簡單 (因為容易理解...) ModelLocator 採用 Flex 綁定機制,UI 顯示資料無煩惱 由於上面兩項,所以使用 Module 開發專案不會很痛苦 討厭的部份: 主要的東西都是 Singleton design pattern, 如果專案很大的話,又統一在一起開發,那個 ModelLocator 到後來應該會很奇怪... 綁太多細節在 UI component 內,如 UI component 一定要認識 ModelLocator 還可以直接操作或修改它...@@ Event 跟 Command 比多的...重點跟 pureMVC 的 command 比起來它的亂多了... 專案越大越亂... pureMVC : 喜歡的部份: 大家的職責切分的很乾淨...棒 (這個只能意會不能言傳啊...XD 快去研究它吧!) 寫在 UI (MXML)內的程式開發起來比使用 Cairngorm 的乾淨好幾倍(因為邏輯層被切分到 Mediator 了) Notification & Command 果然是好物...雖然一開始感覺很囉唆,但是跟它熟了之後發現真是好用... Proxy 比 ModelLocator 更加好用...因為不需要的 Proxy 要清掉也很容易...所以在資料的增減上,pureMVC 架構彈性比較高 簡而言之就是乾淨乾淨乾淨~~~ 討厭的部份: 它的架構比較像仙人一樣超脫於 Flex framework 之上,所以想要整合 Flex 的優點要花點腦袋想(結果這個也是優點...@@) 很多語法都是要繼承並 override 寫起來不夠爽...快,這點 Cairngorm 大量的使用 interface 就棒多了。 由於 Facade 的存在如果要使用 Module 與 MultiCore 版本來開發的話,還需要撰寫連接的元素,或者直接參考 pureMVC網站上的 Utility - AS3 / Pipes 來應用...

[LEGO] How to make an "Unique Random Number" my Block

這篇是答應某人要公開分享的教學...這兩天終於湊出時間來寫... Erin 分享的原則通常都秉持著 "給你魚吃,到不如教你釣魚" 的想法在寫,所以如果沒有附上原始檔也請不用詢問了呦...意思就是我已經提供很多可以讓你"開始學"釣魚的概念囉! 這是去年三月在台北舉辦的 Flex&AIR AUG 網聚上使用的 lotto-bot 中的取得唯一亂數號碼 myBlock,可以用在樂透遊戲或者是亂數只給出現一次的程式應用。它的邏輯很簡單,只是要改成 NXT-G 的 myBlock 花了些時間連連看...XD 開始製作之前請先注意看看你的 NXT-G 有沒有安裝過 Dynamic Block Update ,安裝完成後可以在下拉式功能表中找到 "Block Import and Export Wizard"。接下來請下載及 import Simple Array Block ,在下載的時候請記得點一下畫面中的google AD 感謝 Simple Array 的作者 Steve Hassenplug 提供了很多很棒的NXT-G Blocks 給大家使用。 由於 NXT-G 的變數是全域變數,所以在組合 myBlock 要小心變數命名,取得唯一亂數號碼需要兩個 myBlock ,一個負責初始化相關參數,一個負責輸出唯一號碼: initUniqueRandom myBlock: var uniq_total:Number = total; Simple Array Block : clear Add a value(e.g. 100) to index 0 in Simple Array Block, coz we don't use index 0. If you need it to count from 0, just ignore this step. 如圖: 接下來就麻煩了...很長一串... getUniqueRandom myBlock: 這段要用程式表示囉...不然寫的好累...冏... var Logic 1 : Logic = false; //Logic Switch if(uniq_total == uniq_legth){ //Logic Switch Conditions :

[Flex] pureMVC 練習筆記啪兔

由於 pureMVC Standard and MultiCore 兩個版本寫法幾乎沒啥差別,開發的專案都統一使用彈性比較大的 MultiCore 版本來實作。跟 pureMVC 相處了一陣子後,漸漸地對它也沒有什麼特別的不爽...快,所以 Cairngorm and pureMVC 的選擇,也就由 pureMVC 勝出了(當然是有惡勢力的...冏)。 以下的範例還是使用 pureMVC Standard 來實作喔!這個範例應該能更容易理解 Mediator, Command and Proxy 合作的模式。 1. 由 DataProxy 開始寫 這次的 DataProxy 負責的是將 input textfield 中的文字儲存起來也提供清除的方法。 DataProxy 並不認識任何 Mediator。 package com.mvc.model { import mx.collections.ArrayCollection; import org.puremvc.as3.patterns.proxy.Proxy; public class DataProxy extends Proxy { public static const NAME:String = 'dataProxy'; public static const DATA_UPDATED:String ="data_updated"; public static const SAVE_DATA:String = 'save_data'; public static const CLEAR_DATA:String = 'clear_data'; public function DataProxy() { super(NAME, new ArrayCollection); } public function save(obj:Object):void{ list.addItem(list.length+" : "+obj); sendNotification( DATA_UPDATED, data ); } public function clear():