シリーズのエントリ名変わりました。だから何?という感じですけど。
ひとまずViewHelperとViewLocatorについては、なんとなく理解できたので一応まとめっぽいものです。
ViewHelper
目的
Viewの実装と動作ロジック(主にCommandだと思われる。)を分離する。
動作ロジックとViewががっつり依存しあってる実装だと、Viewの実装が変わった場合のメンテナンス性の悪さとか、ソースコードの見通しの悪さとかがでてきます。
MXMLにごりごりActionScriptが書かれてると、分業するのも大変です。
で、そこでViewHelper。間にこの人に入ってもらって緩和するのです。
ViewHelperには対象となるViewへの参照を持つviewプロパティがあるので、Viewの操作ができます。
概念的なメソッドをインターフェースとしてViewHelperに実装して、動作ロジックからはこのメソッドを呼ぶだけにすれば、ソースの量とトレードオフで、Viewと動作ロジックの分離とソースコードの見通しを確保できる・・・はずです。
使いどころ
よっぽど簡単なViewでない限りは多分どこでも。
動作ロジックであんまり複雑なことをしすぎるのは考え物だと思います。
使い方
ViewHelperをextendしたクラスを実装して、対象となるViewの中で、そのクラスをid属性付で記述します。
Hoge.mxmlならこんな感じ。
<mx:Panel layout="absolute" xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:viewhelper="viewhelper.*"> <viewhelper:HogeViewHelper id="hogeViewHelper"/> </mx:Panel>
そうすると後述するViewLocatorに、HogeViewHelperを標準名「hogeViewHelper」で登録してくれるので、この使い方が一番無難っぽいです。
よくみる例だと、Hoge.mxmlにhugaButtonというButtonがあって、このButtonが押された場合にViewHelperのhuga()を呼ぶ場合は
<mx:Button id="hugaButton" click="hogeViewHepler.huga()"/>
とか、こんな感じだと思うのですが、View→ViewHelperへの参照を極力なくしたいなら、ViewHelperからEventListnerを設定することもできます。
タイミングはViewのcreationCompleteの時がよいと思われます。
具体的には、例えばViewHelperの実装クラスでinitializedをoverrideして、
override public function initialized(document:Object, id:String):void {
super.initialized(document, id);
var hogeForm:HogeForm = HogeForm(this.view);
hogeForm.addEventListener(FlexEvent.CREATION_COMPLETE, this.setEventListener);
}
そして4行目のsetEventListenerを実装。
public function setEventListener(event:Event):void {
var hogeForm:HogeForm = HogeForm(this.view);
hoge.hugaButton.addEventListener(MouseEvent.CLICK, this.huga);
}
とすれば、Hoge.mxmlのhugaButtonにはclick属性は不要となります。
ちなみにちょっとしたおまけなんですが、ViewHelperの実装をinterfaceで定義するのもありかなぁなんて思います。
つまり、こんな感じでIHogeViewHelperを定義すると
(ActionScriptの命名規則ではinterfaceはIで始まります。)
package viewhelper {
import flash.events.Event;
public interface IHogeViewHelper {
/**
* ふがふがします。
* @param event イベント
*
*/
function huga(event:Event):void;
/**
* もがもがします。
*
*/
function moga():void;
}
}
としておけば、HogeViewHelperの実装を強要(正しくはどういうのか不明。Del語です^^;)して
ViewHelperの実装をinterfaceの後ろに隠蔽できます。
そうすると、HogeViewHelperを使うところでは、
var locator:ViewLocator = ViewLocator.getInstance();
var hogeViewHelper:IHogeViewHelper = IHogeViewHelper(locator.getViewHelper("hogeViewHelper"));
hogeViewHelper.moga();
とinterfaceで参照できますから、今度はロジックとViewHelperの結合をゆるくすることができます。
ActionScript用のS2Containerとか出てきた折には、きっとこんな感じになってくるのでしょうね。