FxUGに質問したViewHelperとViewLocatorの使い方なのですが、前々からCairngormをいぢるのに参考にさせて頂いていたサイトの管理人様からレスを頂けました。
おかげでこの件については解決です。
ViewHelperとViewLocatorは
1.ViewHelperはView(MXML)で宣言して使う。
2.この方法で宣言したViewHelperはViewLocatorのgetViewHelperで取得できる。
という使い方で大体あっているということでしたので、やっぱりView(MXML)からViewHelperの宣言はなくさないということです。
ModelLocatorについては、ViewHelperに移動すればView(MXML)からはなくすることができるということも教えていただきました。
目標として考えていた
1.ViewからViewHelperエレメントをなくす。
2.ViewからModelLocatorをなくす。(Scriptエレメント)
3.Viewからclick="viewHelper.hoge()"属性をなくす。
という目標のうち、1.はやめた方がよさげ。2.は成功です。
残すところの3.なのですが、
ViewHelperの実装クラスでinitializedをオーバライドしてプロパティviewのButton要素にaddEventListenerしてみようと思ったのですが、あいにくinitializedの時点ではィviewのButton要素はnullでありました。
よって3.はあえなく撃沈です。
達成できたのは2.だけですが、Scriptエレメントをなくせただけでもかなりすっきりです。
>あと、もしServiceとかをmxml内でインスタンス化するのが気持ち悪かったらFrontControllerでインスタンス化するのも手だと思われます。
という情報も頂けたので、これは調べてみないとですね。
さてさて、結局のところのViewHelperの実装なのですが、interfaceを定義して、それをimplementして実装することに致しました。
この形ならViewHelperとViewHelperを使う先の関係が薄くなるのと、実装との分業も可能になります。
(リソースやパフォーマンスとトレードオフということですが)
それにのViewHelperの実装のinterfaceのメソッド定義には、概念的なonLoginとかonItemAddedといったメソッドを定義しておけば、ViewHelperを使う側からはかなり概念に近いレベルで使えると思います。
当然実装側は参照側に実装を強要できますし。
この形に変えたNoelPortalのCommandクラスはかなりシンプルです。
package jp.systemsnoel.noelportal.command {
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import flash.events.Event;
import jp.systemsnoel.noelportal.business.LoginDelegate;
import jp.systemsnoel.noelportal.dto.User;
import jp.systemsnoel.noelportal.event.LoginEvent;
import jp.systemsnoel.noelportal.modellocator.LoginModelLocator;
import mx.controls.Alert;
import mx.rpc.IResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import jp.systemsnoel.noelportal.component.userinfopanel.viewhelper.IUserInfoPanelViewHelper;
import com.adobe.cairngorm.view.ViewLocator;
/**
* ログイン処理を実行するコマンドです。
* 処理をLoginDelegateにDelegateするので、コールバック関数も実装されています。
* @author m_aoki
*
*/
public class LoginCommand implements ICommand, IResponder {
/**
* ModelLocator
*/
private var model:LoginModelLocator = LoginModelLocator.getInstance();
/**
* このコマンドが実行される際に実行されるメソッドです。
* @param event Event
*
*/
public function execute(event:CairngormEvent):void {
var loginEvent:LoginEvent = LoginEvent(event);
var delegate:LoginDelegate = new LoginDelegate(this);
delegate.login(loginEvent.uid, loginEvent.password);
}
/**
* Delegateの処理が完了した際に呼ばれるコールバックです。
* @param data Object
*
*/
public function result(data:Object):void {
var event:ResultEvent = ResultEvent(data);
//戻りがnullだった場合は、IDもしくはPassでの認証失敗です。
if(event.result == null) {
Alert.show("Login falut");
//そうでなかった場合にはログイン成功として現在のユーザを設定してビューステートを変更します。
} else {
var user:User = event.result as User;
model.user = user;
var locator:ViewLocator = ViewLocator.getInstance();
var userInfoPanelViewHelper:IUserInfoPanelViewHelper = IUserInfoPanelViewHelper(locator.getViewHelper("userInfoPanelViewHelper"));
userInfoPanelViewHelper.onLogin();
var noelPortalViewHelper:INoelPortalViewHelper = INoelPortalViewHelper(locator.getViewHelper("noelPortalViewHelper"));
noelPortalViewHelper.onLogin();
}
}
/**
* Delegateで処理が失敗した場合に呼ばれるコールバックです。
* @param info Object
*
*/
public function fault(info:Object):void {
var faultEvent:FaultEvent = FaultEvent(info);
Alert.show(faultEvent.fault.faultString);
}
}
}
今度は教えていただいてServiceの使い方について調べてみましょう。