3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Flex Framework Mate の基本的な使い方 その2

Last updated at Posted at 2014-06-30

前回の続きです。
http://qiita.com/tajihiro/items/61a377c17b99fcff453c

サンプル

下記の図のようなサンプルです。
テキストフィールドに入力した言葉を、ラベルに返すサンプルです。

input.png
 ↓
output.png

ソースコード解説

アプリケーションエントリ

Index.mxmlは、アプリケーションのエントリとなるmxmlファイルです。
ここでは、Viewコンポーネントである MainView.mxml(View)を配置し、MainView上で発生するイベントをマッピングする MainViewEventMap.mxml (EventMap)を定義します。

Index.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   minWidth="955"
			   minHeight="600"
			   xmlns:view="main.view.*"
			   xmlns:map="main.map.*">
	<fx:Declarations>
		<!-- 使用するEventMapを 以下に追記する -->
		<map:MainViewEventMap/>

	</fx:Declarations>

	<s:Group top="20"
			  left="20">
		<!--MainViewを配置する-->
		<view:MainView/>
	</s:Group>
</s:Application>

イベントマップ
このファイルは、Index.mxmlファイル内で呼び出されます。

イベントマップファイルの中では、Flexの初期イベントであるPREINITIALIZEイベントを受けて、MainViewModelクラスをインスタンス化します。
その際、モデルのコンストラクタにて scope.dispathcer を注入(DI)してあげます。

イベントハンドラのマッピング定義ですが、EventHandlersタグの、typeで指定したイベントを受け取ると、MethodInvokerのgeneratorで指定したモデルクラスのメソッドを呼び出します。

Injectorsにてターゲットに Viewコンポーネントを指定し、使用するモデルを定義します。ここで指定する targetKeyで指定した識別子が、Viewが使用するモデルの変数名となります。

MainViewEventMap.mxml
<?xml version="1.0" encoding="utf-8"?>
<mt:EventMap xmlns:fx="http://ns.adobe.com/mxml/2009"
			 xmlns:s="library://ns.adobe.com/flex/spark"
			 xmlns:mx="library://ns.adobe.com/flex/mx"
			 xmlns:mt="http://mate.asfusion.com/">

	<fx:Script>
		<![CDATA[
			import main.event.MainViewEvent;
			import main.model.MainViewModel;
			import main.view.MainView;

			import mx.events.FlexEvent;
		]]>
	</fx:Script>

	<fx:Declarations>
		<!-- Modelのインスタンス化 dispatcherを引数とする -->
		<mt:EventHandlers type="{FlexEvent.PREINITIALIZE}">
			<mt:ObjectBuilder generator="{MainViewModel}"
							  constructorArguments="{scope.dispatcher}"/>
		</mt:EventHandlers>

		<!-- Eventに対応するModel内のメソッドを定義する パラメータは event より取得-->
		<mt:EventHandlers type="{MainViewEvent.EXEC_FUNC_1}">
			<mt:MethodInvoker generator="{MainViewModel}"
							  method="func1"
							  arguments="{event.inputData}"/>
		</mt:EventHandlers>

		<!-- ViewにModelをインジェクトする -->
		<mt:Injectors target="{MainView}">
			<mt:PropertyInjector source="{MainViewModel}"
								 targetKey="model"/>
		</mt:Injectors>

	</fx:Declarations>
</mt:EventMap>

Viewコンポーネント
Viewコンポーネントファイルでは、ボタン等のコンポーネントを配置します。
また、[Bindable]なモデルクラスを定義します。

Viewで発生したイベントは、そのイベントハンドラの中で、そのModelファイルへ処理を受け渡します。
この例では、ボタンのクリックイベントに対応した myButton_clickHandler(event)の中で、そのModelクラスのclickHandlerメソッドを、TextInputに入力した文字列を引数にして呼び出しています。

Main.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:VGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
		  xmlns:s="library://ns.adobe.com/flex/spark"
		  xmlns:mx="library://ns.adobe.com/flex/mx"
		  width="400"
		  height="300">

	<fx:Script>
		<![CDATA[
			import main.model.MainViewModel;

			[Bindable]
			public var model:MainViewModel;

			//クリックハンドラ
			protected function myButton_clickHandler(event:MouseEvent):void
			{
				//モデルのクリックハンドラメソッドを呼ぶ
				this.model.clickHandler(this.myText.text);
			}
		]]>
	</fx:Script>

	<fx:Declarations>
		<!-- 非ビジュアルエレメント (サービス、値オブジェクトなど) をここに配置 -->
	</fx:Declarations>

	<s:HGroup>
		<s:TextInput id="myText"
					 text="こんにちは。"/>
		<s:Button id="myButton"
				  label="OK"
				  click="myButton_clickHandler(event)"/>
	</s:HGroup>

	<s:Spacer height="30"/>

	<s:HGroup>
		<s:Label text="戻り値:"/>
		<s:Label id="result"
				 text="{this.model.result}"/>
	</s:HGroup>
</s:VGroup>

モデルクラス

モデルクラスは、Viewでのイベントハンドラ処理等のロジックを記述します。
または、イベントディスパッチされたイベントの後処理を記述します。

MainViewModel.as
package main.model
{
	import com.asfusion.mate.events.Dispatcher;

	import flash.events.IEventDispatcher;
	import flash.events.MouseEvent;

	import main.event.MainViewEvent;
	import main.view.MainView;

	import mx.controls.Alert;

	public class MainViewModel
	{
		/**
		 * コンストラクタ
		 */
		public function MainViewModel(dispatcher:IEventDispatcher)
		{
			this.dispatcher=dispatcher;
		}

		//親クラスで定義した方が便利
		protected var dispatcher:IEventDispatcher;

		/**
		 * プロパティ
		 */
		private var _result:String;

		/**
		 * プロパティ Getter/Setter
		 */
		[Bindable]
		public function get result():String
		{
			return _result;
		}

		/**
		 * @private
		 */
		public function set result(value:String):void
		{
			_result=value;
		}

		/**
		 * クリックハンドラ(Viewから呼ばれる)
		 */
		public function clickHandler(value:String):void
		{
			var event:MainViewEvent=new MainViewEvent(MainViewEvent.EXEC_FUNC_1);
			//Eventにパラメータを設定
			event.inputData=value;
			this.dispatcher.dispatchEvent(event)
		}

		/**
		 * イベントディスパッチされたハンドラ(EventMapから呼ばれる)
		 */
		public function func1(param:Object):void
		{
			var str:String=param as String;
			result=str;
//			Alert.show("func1:" + str);
		}
	}
}

Eventクラス

Eventクラスは、 flash.events.Eventクラスを継承しており、イベントの定義を行います。
イベントクラス内では、発生したイベントにパラメータを含めたい場合には、インスタンス変数を定義します。

MainViewEvent.as
package main.event
{
	import flash.events.Event;

	public class MainViewEvent extends Event
	{
		public static const NAME:String="MainViewEvent";

		//イベント名
		public static const EXEC_FUNC_1:String="execFunc1" + NAME;

		//パラメータデータ
		public var inputData:String;

		public function MainViewEvent(type:String, 
						bubbles:Boolean=false,
						cancelable:Boolean=false)
		{
			super(type, bubbles, cancelable);
		}
	}
}

以上、FlexのフレームワークであるMateの基本的な解説でした。
最初は複雑なので戸惑います。
ソースコードや、イベントディスパッチを追うのがとても面倒なのですが、大規模開発の見通しは良いと思います。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?