StarlingMVC Framework中文教程
2019獨角獸企業重金招聘Python工程師標準>>>
配置與開始
將Starling項目配置為StarlingMVC項目,僅需幾行代碼。在繼承于starling.display.Sprite的起始類里,創建一個StarlingMVC的實例,并傳遞給它三個參數:Starling顯示對象的根對象(起始類的實例)、StarlingMVCConfig的實例,以及一些Beans(數組或BeanProvider)。
package com.mygame.views {import com.creativebottle.starlingmvc.StarlingMVC;import com.creativebottle.starlingmvc.config.StarlingMVCConfig;import com.creativebottle.starlingmvc.views.ViewManager;import com.mygame.models.GameModel;import starling.core.Starling;import starling.display.Sprite;public class GameMain extends Sprite{private var starlingMVC:StarlingMVC;public function GameMain(){var config:StarlingMVCConfig = new StarlingMVCConfig();config.eventPackages = ["com.mygame.events"];config.viewPackages = ["com.mygame.views"];var beans:Array = [new GameModel(), new ViewManager(this)];starlingMVC = new StarlingMVC(this, config, beans);}} }StarlingMVCConfig的實例告訴StarlingMVC它應該處理的事件包及視圖包的位置。Beans數組僅僅是一組對象集合,可以包括任何類型的對象,框架會區別待之。(譯者注:框架僅處理在視圖包下的view對象的[ViewRemoved]標簽,在處理[EventHandler]標簽時,也僅處理事件包下的事件類型。)
在Flash Builder上的額外設置
使用Flash?builder編譯產品,AS編譯器會嚴格剝離非標準的Metadata標簽,除非另有指定。StarlingMVC的自定義標簽對于實現強大的自動依賴注入特征是必須的,如果沒有這些標簽,StarlingMVC將毫無作用。
使編譯器充許StarlingMVC的自定義標簽非常簡介,僅需在項目上添加幾行額外的編譯參數即可。
為添加編譯參數,右鍵單擊項目,選擇”Properties“,然后選擇”ActionScript Compiler“,在“Additional compiler arguments”后面追加:
-keep-as3-metadata+=Dispatcher-keep-as3-metadata+=EventHandler
-keep-as3-metadata+=Inject
-keep-as3-metadata+=Juggler
-keep-as3-metadata+=PostConstruct
-keep-as3-metadata+=ViewAdded
-keep-as3-metadata+=ViewRemoved
這樣StarlingMVC便可以工作了。
Beans
一個Bean是一個提供給StarlingMVC管理的一個對象的實例。Bean們可以被注入,接收注入,還有接收事件等。在StarlingMVC的配置階段,有多種方式可以設置Bean元素:
對象實例
var beans:Array = [new GameModel(), new ViewManager(this)];Bean實例
var beans:Array = [new Bean(new GameModel()), new Bean(new ViewManager(this))];以上提供Bean實例的設置方法相比之下并無高明之處,但是Bean的構造器的第二個參數可以傳遞一個id。只有提供了id,在依賴注入時才可以使用。另外,如果沒有提供id,Bean將以class type作key在框架中存儲,如果你有兩個類型相同的Bean,必須提供id,否則后者將覆蓋前者。例:
var beans:Array = [new Bean(new GameModel(),"gameModelEasy"),new Bean(new GameModel(),"gameModelHard"), new ViewManager(this)];BeanProvider實例
BeanProvider是Bean的集合,與簡單的Bean數組相同,在BeanProvider內的bean,可以是任何類型,包括BeanProvider。
package com.mygame.config {import com.creativebottle.starlingmvc.beans.BeanProvider;import com.mygame.assets.AssetModel;import com.mygame.models.AudioModel;import com.mygame.models.GameModel;public class Models extends BeanProvider{public function Models(){beans = [new GameModel(), new Bean(new AudioModel(),"audioModel"), new AssetModel()];}} }有了BeanProvider,便可以把它作為元素之一以數組的方式提供bean:
var beans:Array = [new Models(), new ViewManager(this)];ProtoBeans
ProtoBean是在被注入才會被創建的Bean。一般的Bean要求提供一個類實例,ProtoBean要求提供一個類定義及一個id。
var beans:Array = [new ProtoBean(Character,"character"), new ViewManager(this)];這里使用ProtoBean將充許StarlingMVC為你創建類的實例。它每一次被注入,均會實例化一個新的類的實例,在這種情況下,使用”Character”類而不是像一般的Bean那樣使用一個單例。讓StarlingMVC框架去創建一個類的實例,而不是使用”new Character()”創建的好處在于,前者可以被注入、監管事件等處理所有依賴注入事務。
依賴注入
依賴注入發生在所有Bean及所有Starling對象上。在公開屬性或gettter/setter標以[Inject]無數據標簽便是一個依賴項。一個注入可以這樣定義:
package com.mygame.controllers {public class GameController{[Inject]public var gameModel:GameModel;public function GameController():void{}} }或者以id注入,如果id在指定Bean時已經提供了的話:
package com.mygame.controllers {public class GameController{[Inject(source="gameModel")]public var gameModel:GameModel;public function GameController():void{}} }在上面的例子中,如果GameModel是一個普通的Bean,框架會以在配置時創建的單例賦值它。如果它是一個Protobean,框架會創建一個實例再注入到變量中。
StarlingMVC同樣支持注入Bean的屬性。為了使用這個功能,源Bean必須有一個id(在配置時使用new Bean指定的id)。注入Bean的屬性,在[Inject]內bean id加上“.”+屬性的名稱即可:
package com.mygame.controllers {public class GameController{[Inject(source="gameModel")]public var gameModel:GameModel;[Inject(source="userModel.currentUser")]public var currentUser:User;public function GameController():void{}} }在上面的例子中,userModel的屬性currentUser將會注入到我們的控制器的currentUser屬性上。這個功能還支持遞歸,如果你想注入currentUser的firstName屬性,你可以這樣做:
[Inject(source="userModel.currentUser.firstName")].
綁定
注入操作同樣支持簡單的綁定機制,當源對象發生變化時,被注入的屬性將會被自動更新。
package com.mygame.controllers {public class GameController{[Inject(source="gameModel")]public var gameModel:GameModel;[Inject(source="userModel.currentUser", bind="true")]public var currentUser:User;public function GameController():void{}} }如上所示,在[Inject]標簽中使用一個bind=”true”的參數實現綁定。userModel的currentUser屬性變化之時,StarlingMVC將自動更新所有使用綁定的注入。此招同樣適用于getter/setters方法,運用此法可使代碼輕而易舉地的實現屬性的變化。
package com.mygame.controllers {public class GameController{[Inject(source="gameModel")]public var gameModel:GameModel;[Inject(source="userModel.currentUser", bind="true")]public function set currentUser(value:User):void{_currentUser = value;// Do something to update your UI with the new value}public function get currentUser():User{return _currentUser;}private var _currentUser:User;public function GameController():void{}} }綁定與Starling juggler相連,這意味著它會在每次advanceTime()方法被調用的時候自動檢查綁定的屬性的變化。這不同于Flex提供的即時綁定。綁定應該謹慎使用,因為檢查綁定的屬性變化是一個不小的開銷。
做為自動綁定屬性的另外一種選擇,StarlingMVC支持通過使之失效的方式綁定。這個方法相對于自動綁定十分有效,因為在當屬性更新時它給了你更多的控制。這個功能可以通過一個被注入的Bindings類例和一個”auto”參數實現:
package com.mygame.controllers {public class GameController{[Inject(source="gameModel")]public var gameModel:GameModel;[Inject(source="userModel.currentUser", bind="true", auto="false")]public function set currentUser(value:User):void{_currentUser = value;// Do something to update your UI with the new value}public function get currentUser():User{return _currentUser;}private var _currentUser:User;public function GameController():void{}} }package com.mygame.models {public class UserModel{[Bindings]public var bindings:Bindings;public function set currentUser(value:User):void{if(value != _currentUser){_currentUser = value;bindings.invalidate(this, "currentUser");}}public function get currentUser():User{return _currentUser;}private var _currentUser:User;} }事件
派發事件
StarlingMVC的事件通過兩種渠道派發:1)StarlingMVC包含一個全局的starling.events.EventDispatcher的實例,派發事件的一個快速方法便是使用這個dispatcher。該dispatcher可以通過[Dispatcher]元數據標簽被注入到任何一個Bean內。?2)顯示對象可以使用自有的dispatchEvent()方法派發事件。該方法僅當事件bubble設置為true時有效。
處理事件
事件處理被指示為在bean的公開方法上添加[EventHandler(event="")]元數據標簽。標簽內事件的參數有兩種寫法:一為事件類型字符串
package com.mygame.controllers {public class GameController{[EventHandler(event="scoreChanged")]public function scoreChanged(event:ScoreEvent):void{}} }另一個為事件定義字符串:
package com.mygame.controllers {public class GameController{[EventHandler(event="ScoreEvent.SCORE_CHANGED")]public function scoreChanged(event:ScoreEvent):void{}} }使用第二種方式的好處,在于StarlingMVC會在事件初始化時檢查事件類型是否真實存在,如果不存在,將拋出異常。另外還可以防止錯誤字。(譯者注:這是StarlingMVC要求開發者提供的eventsPackage的原因。)
在上述兩個例子中,處理函數必須接受一個派發的事件并處理。然而,[EventHandler]標簽的第二個參數充許你指定事件的哪些屬性將被傳遞給事件處理函數。例如:
package com.mygame.controllers {public class GameController{[EventHandler(event="ScoreEvent.SCORE_CHANGED", properties="user, newScore")]public function scoreChanged(user:User, newScore:int):void{}} }如上所示,StarlingMVC沒有傳遞一個event整體給事件函數,而只是傳遞事件的”user” 與 “newScore”屬性。注意:類型必須匹配,否則將會報錯。
視圖中間件
視圖中間件是保持你的視圖類與控制它們的代碼分離的一種好方法。視圖中間件的設定與其它Bean一樣。使用[ViewAdded]元數據標簽將一個視圖鏈接到一個視圖中間件之上。當視圖被添加進顯示列表之后,StarlingMVC將會檢查所有標以[ViewAdded]標簽的方法,如果被標識的方法的view參數的類型與被添加進顯示列表的視圖類型相同,顯示對象將被傳遞進方法。同理,[ViewRemoved]標簽用于當視圖被從顯示列表移除時所要執行的函數的注入。
package com.mygame.mediators {public class GameMediator{private var view:Game;[ViewAdded]public function viewAdded(view:Game):void{this.view = view;}[ViewRemoved]public function viewRemoved(view:Game):void{this.view = null;}} }Bean的生命周期
一般情況下,bean被設置了初始化。但是,在bean被創建之后,依賴注入與事件監聽并沒有立即可用。為了在當bean完成注入時得到一個通知,我們可以在一個公開方法上添加[PostConstruct]標簽,這個方法會在注入完成后被自動調用。同樣的,當一個bean被銷毀時,我們可以在一個公開方法上標以[PreDestroy]標簽。該功能在所有標準bean及顯示對象上可用。
package com.mygame.controllers {public class GameController{[Inject]public var gameModel:GameModel;[PostConstruct]public function postConstruct():void{// set up code here}[PreDestroy]public function preDestroy():void{// tear down code here}[EventHandler(event="ScoreEvent.SCORE_CHANGED", properties="user, newScore")]public function scoreChanged(user:User, newScore:int):void{}} }package com.mygame.controllers {public class GameModel{[Bindings]public var bindings:Bindings;public function set score(value:int):void{if(value != _score){_score = value;bindings.invalidate(this, "score");}}public function get score():int{return _score;}private var _score:int;} }手動添加、移除Bean
手動添加、移除bean是通過事件完成的,派發BeanEvent.ADD_BEAN事件用于添加、處理一個新的bean,派發BeanEvent.REMOVE_BEAN事件將bean從系統移除。
package com.mygame.view {public class Game{public var gamePresentationModel:GamePresentationModel;[PostConstruct]public function postConstruct():void{gamePresentationModel = new GamePresentationModel();dispatchEvent(new BeanEvent(BeanEvent.ADD_BEAN, gamePresentationModel));}[PreDestroy]public function preDestroy():void{dispatchEvent(new BeanEvent(BeanEvent.REMOVE_BEAN, gamePresentationModel));gamePresentationModel = null;}} }所上所示,我們為視圖創建一個Model并且作為一個bean添加進StarlingMVC。Model將被作為一個bean處理,并馬上獲得注入與事件處理的優勢。
Command模式
StarlingMVC包括對Command模式的支持。Command本質上是事件派發,執行,銷毀時被創建的Bean。向框架添加command,需要在bean里添加Command類定義。
package com.mygame.views {import com.creativebottle.starlingmvc.StarlingMVC;import com.creativebottle.starlingmvc.config.StarlingMVCConfig;import com.creativebottle.starlingmvc.views.ViewManager;import com.mygame.models.GameModel;import starling.core.Starling;import starling.display.Sprite;public class GameMain extends Sprite{private var starlingMVC:StarlingMVC;public function GameMain(){var config:StarlingMVCConfig = new StarlingMVCConfig();config.eventPackages = ["com.mygame.events"];config.viewPackages = ["com.mygame.views"];var beans:Array = [new GameModel(), new ViewManager(this), new Command(DoSomethingEvent.DO_SOMETHING, DoSomethingCommand)];starlingMVC = new StarlingMVC(this, config, beans);}} }這將映射事件到Command。command類可以像其它bean一樣接收注入,但不能接收事件,事件也只在執行單個command的周期內存在。在command內將執行的方法被標為[Execute]標簽。
package com.mygame.commands {import com.mygame.events.NavigationEvent;import com.mygame.models.BubbleModel;import starling.events.EventDispatcher;public class DoSomethingCommand{[Dispatcher]public var dispatcher:EventDispatcher;[Inject]public var bubbleModel:BubbleModel;[Execute]public function execute(event:DoSomethingEvent):void{trace("did something!");}} }所上所示,當DoSomethingEvent.DO_SOMETHING事件被派發時,StarlingMVC將創建一個DoSomethingCommand的實例,執行execute方法,然后銷毀它。Command類可以在標簽中包括一個runOnce的可選參數。
package com.mygame.views {import com.creativebottle.starlingmvc.StarlingMVC;import com.creativebottle.starlingmvc.config.StarlingMVCConfig;import com.creativebottle.starlingmvc.views.ViewManager;import com.mygame.models.GameModel;import starling.core.Starling;import starling.display.Sprite;public class GameMain extends Sprite{private var starlingMVC:StarlingMVC;public function GameMain(){var config:StarlingMVCConfig = new StarlingMVCConfig();config.eventPackages = ["com.mygame.events"];config.viewPackages = ["com.mygame.views"];var beans:Array = [new GameModel(), new ViewManager(this), new Command(DoSomethingEvent.DO_SOMETHING, DoSomethingCommand, true)];starlingMVC = new StarlingMVC(this, config, beans);}} }在這個例子中,一個command bean以這樣的語句被添加:new Command(DoSomethingEvent.DO_SOMETHING, DoSomethingCommand, true)。最后的參數true,標識該comand只被運行一次。所以,當DO_SOMETHING事件被派發時,DoSomethingCommand的實例被框架創建,執行,最后銷毀,并從映射中移除。這個功能在初始化時非常有用(譯者注:指執行一次)。
EventMap
EventMap is a utility class for creating and managing event listeners. Using EventMap exclusively to create listeners within your class makes cleanup very easy.
EventMap是一個創建、管理事件監聽的工具類。使用EventMap創建的事件監聽易于清理。
package com.mygame.mediators {import com.creativebottle.starlingmvc.events.EventMap;public class GameMediator{private var eventMap:EventMap = new EventMap();[ViewAdded]public function viewAdded(view:Game):void{eventMap.addMap(view.playButton,TouchEvent.TOUCH, playButtonTouched);eventMap.addMap(view.instructionsButton,TouchEvent.TOUCH, instructionsTouched);}[ViewRemoved]public function viewRemoved(view:Game):void{event.removeAllMappedEvents();}private function playButtonTouched(event:TouchEvent):void{}private function instructionsButtonTouched(event:TouchEvent):void{}} }Juggler
Starling的juggler用于管理游戲內的所有動畫。對于一個使用Juggler便利的類,必須實現IAnimatable接口、定義
advanceTime(time:Number)方法。全局的juggler引用可以通過這個實例屬性訪問:Starling.juggler。并且,這個屬性可以使用[Juggler]標簽被直接注入到bean中。(譯者注:StarlingMVC1.1源碼有一個專門的Processor用于處理Juggler的注入)
package com.mygame.mediators{import com.creativebottle.starlingmvc.events.EventMap;public class GameMediator implements IAnimatable{[Juggler]public var juggler:Juggler;[ViewAdded]public function viewAdded(view:Game):void{juggler.add(this);}[ViewRemoved]public function viewRemoved(view:Game):void{juggler.remove(this);}public function advanceTime(time:Number):void{// do some animation logic}}}ViewManager
ViewManager是一個工具類,通過它可以用來在舞臺上添加刪除視圖。當我們創建ViewManager事例的時候,我們需要傳遞一個根顯示對象。這樣我們通過ViewManager可以在Starling的任意位置方便的添加可視化交互內容。
設置視圖
調用setView將會移除已有的視圖并且添加新的視圖。ViewManager處理實例化視圖,并將其添加到堆棧中。
package com.mygame.controllers {public class NavigationController{[Inject]public var viewManager:ViewManager;[EventHandler(event="NavigationEvent.NAVIGATE_TO_VIEW", properties="viewClass")]public function navigateToView(viewClass:Class):void{viewManager.setView(viewClass);}} }添加視圖
調用addView方法將在現有視圖上添加一個新的視圖。這里通過addView方法將GameHUD類型的視圖添加到現有視圖管理器中。
package com.mygame.views {public class Game{[Inject]public var viewManager:ViewManager;private var hud:GameHUD;[PostConstruct]public function postConstruct():void{hud = new GameHUD();viewManager.addView(hud);}} }移除視圖
通過調用removeView可以刪除堆棧中制定的視圖。
移除所有視圖
調用removeAll可以移除堆棧中存在的所有視圖。當你調用setView()的時候這個方法會被自動調用。
轉載于:https://my.oschina.net/zhepama/blog/265038
總結
以上是生活随笔為你收集整理的StarlingMVC Framework中文教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS中设置ip地址等信息
- 下一篇: android中播放gif动画之二