イベントによる Flex コンポーネントの連携

当面 Apollo の開発環境が Flex Builder のみとのことで Flex 入門も兼ねてと書き始めたら (今頃すみません) 思っていたより長引いてます。

さて、前回のコードでは、以下の通り MyBrowser.mxml から HTMLControlBar コンポーネントにイベントの発生を伝えるためにメソッドを呼び出していました。

// MyBrowser.mxml
private function onDomInitialize(e:Event):void {
  htmlControl.onDomInitialize();
}
 

これは2つのコンポーネントの依存関係を強くしますし、そもそも HTML コンポーネントへの参照を HTMLControlBar コンポーネントに渡しているのに別途イベントを伝えるコードも在るのは冗長なように思われます。

そこで、この箇所を変更してみたいと思います。

domInitialize イベントが発生したら処理を行うというのは HTMLControlBar コンポーネントの都合です。なのでイベントを受け取る設定は HTMLControlBar コンポーネント側のみで完結するようにします。具体的には、”HTMLControlBar コンポーネントは HTML コンポーネントへの参照が target 属性に渡されたら HTML コンポーネントの domInitialize イベントへのリスナを登録する” ようにしたいと思います。

そのために set を使うことにします。set は get と対になるプロパティへのアクセスを実現する機能です。以前に解説を書いたことがありますのでより詳しい説明はそちらをご参照くさい。(get と set

set を使うと target 属性は以下のように書き直すことができます。

private var _target:HTML;
 
public function set target(value:HTML):void {
  _target = value;
}
 

この形であれば、set 関数内部でイベントリスナを登録することも可能です。下のコードでは Event.DOM_INITIALIZE イベントに対して onDomInitialize() メソッドをリスナとして登録しています。これで target で domInitialize イベントが発生したら onDomInitialize() が呼ばれるようになります。

private var _target:HTML;
 
public function set target(value:HTML):void {
  _target = value;
  _target.addEventListener(Event.DOM_INITIALIZE, onDomInitialize);
}
 

HTML コンポーネントは一つとは限らないかもしれません。念のため古いリスナが登録されていたら削除するコードも追加してみます。

private var _target:HTML;
 
public function set target(value:HTML):void {
  if (_target != null) {
    _target.removeEventListener(Event.DOM_INITIALIZE, onDomInitialize);
  }
  _target = value;
  _target.addEventListener(Event.DOM_INITIALIZE, onDomInitialize);
}
 

今のところ必要なさそうですが、念のため get も定義しておきます。

public function get target():HTML {
  return _target;
}
 

以上で HTMLControlBar コンポーネント内に HTML コンポーネントへのイベントリスナを設定する機能も実装されました。

従って、MyBrowser.mxml からは HTML コンポーネントの domInitialize イベント関連の記述は全て削除可能になります。

最後に全ファイルのコードです。

MyBrowser.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:ApolloApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">
  <mx:Script>
    <![CDATA[
      private function onLocationChange(e:Event):void {
        html.alpha=0
      }
      private function onComplete(e:Event):void {
        fadeIn.target = html;
        fadeIn.play();
      }
    ]]>
  </mx:Script>
  <mx:Style source="MyBrowser.css"/>
  <mx:Fade id="fadeIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
 
  <local:HTMLControlBar id="htmlControl" target="{html}"/>
  <mx:HTML id="html" width="100%" height="100%"
    locationChange="onLocationChange(event)" complete="onComplete(event)"/>
</mx:ApolloApplication>
 

HTMLControlBar.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">
  <mx:Script>
    <![CDATA[
      import mx.controls.HTML;
      private var _target:HTML;
 
      public function set target(value:HTML):void {
        if (_target != null) {
            _target.removeEventListener(Event.DOM_INITIALIZE, onDomInitialize);
        }
        _target = value;
        _target.addEventListener(Event.DOM_INITIALIZE, onDomInitialize);
      }
      public function get target():HTML {
        return _target;
      }
      private function onDomInitialize(event:Event):void {
        prevLocations.pushLocation(_target.location);
        inputTF.text = _target.location;
      }
      private function back():void {
        var prevURL:String = prevLocations.popLocation();
        if (prevURL != null) {
          setLocation(prevURL);
        }
      }
      private function setLocation(url:String):void {
        _target.location = url;
      }
    ]]>
  </mx:Script>
  <local:PreviousLocations id="prevLocations"/>
  <mx:TextInput id="inputTF" width="225" text="http://" enter="setLocation(inputTF.text)"/>
  <mx:Button label="移動" click="setLocation(inputTF.text)"/>
  <mx:Button label="戻る" click="back()" enabled="{prevLocations.isPopEnabled}"/>
</mx:HBox>
 

PreviousLocations.as

package
{
  public class PreviousLocations
  {
    private var history:Array = new Array();
    private var isPop:int = 0;
 
    [Bindable]
    public var isPopEnabled:Boolean = false;
    private function setPopEnabled():void {
      isPopEnabled = history.length > 1;
    }
 
    public function popLocation():String {
      var prevLocation:String = null;
      if (history.length > 1) {
        history.pop();
        setPopEnabled();
        prevLocation = history[history.length - 1];
        isPop++;
      }
      return prevLocation;
    }
    public function pushLocation(location:String):void {
      if (isPop > 0) {
        isPop--;
      } else {
        history.push(location);
        setPopEnabled();
      }
    }
  }
}
 

MyBrorser.css

Application {
   background-color:"";
   background-image:"";
   background-alpha: 0.4;
}
 

コメントする

2014年1月

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
レンタルサーバー

月別 アーカイブ

Powered by Movable Type 4.261