このエントリ名でやってると大変なことになりそうなので、次回からエントリ名を変えることに致しますです^^;
FxUGに質問して解決した部分とあきらめた部分があった「MXMLからロジック抜きたいよ」作戦なのですが、更なるご意見を頂いてもっといい形になりました。
これが今考えられる一番いい形だと(あくまで個人的に)思います。
今度は何が実現したかというと、前回あきらめたMXMLに記載したコンポーネントからViewHelperのメソッドへの参照をなくすことができました。
<mx:Button x="183" y="66" label="Login" id="btnLogin" click="hogeViewHelper.login()"/>
ここの「click="hogeViewHelper.login()」の部分をなくすのです。
これでMXMLに残ったのはViewHelperの宣言箇所のみです。ここはViewLocaterへの登録も行ってくれているところなので、ここをなくすとなると、かなりライフサイクルを意識した実装が必要になりそうなので、ここで完結という気がします。
で、気になるそのメソッドへの参照をなくす方法というのが、ViewHelperのviewプロパティ、つまり管理対象のビューのcreationCompleteのタイミングで、上の例でいくならbtnLoginにMouseEvent.CLICKでaddEventListenerすればいいということです。
Flexではそのフェーズごとにイベントが発生するわけですから、そこできちんと設定してあげればいいわけですね。
JSFとかで、へろへろになった記憶も生々しいあたりでもございます^^;
えー、気を取り直して^^;
こんな感じのLoginViewHelperを実装すれば、これで解決。
package jp.systemsnoel.noelportal.component.loginform.viewhelper {
import com.adobe.cairngorm.control.CairngormEventDispatcher;
import com.adobe.cairngorm.view.ViewHelper;
import flash.events.Event;
import flash.events.MouseEvent;
import jp.systemsnoel.noelportal.component.loginform.LogInForm;
import jp.systemsnoel.noelportal.event.LoginEvent;
import mx.events.FlexEvent;
public class LoginViewHelper extends ViewHelper implements ILoginViewHelper {
override public function initialized(document:Object, id:String):void {
super.initialized(document, id);
var logInForm:LogInForm = LogInForm(this.view);
logInForm.addEventListener(FlexEvent.CREATION_COMPLETE, this.setEventListener);
}
public function dispatchLoginEvent(evnt:Event):void {
var loginEvent:LoginEvent = new LoginEvent(LoginEvent.LOGIN);
var logInForm:LogInForm = LogInForm(this.view);
loginEvent.uid = logInForm.txtUID.text;
loginEvent.password = logInForm.txtPwd.text;
CairngormEventDispatcher.getInstance().dispatchEvent(loginEvent);
}
public function setEventListener(event:Event):void {
var logInForm:LogInForm = LogInForm(this.view);
logInForm.btnLogin.addEventListener(MouseEvent.CLICK, this.dispatchLoginEvent);
}
}
}
今回はnitializedをoverrideして、その中でFlexEvent.CREATION_COMPLETEに対するリスナメソッド「setEventListener(event:Event)」を登録して、その中で対象コンポーネントのイベントリスナの登録を行っているのです。
この方法は何か他にも応用がききそうです。すばらしい。