- 2005-10-19 (水)
- ActionScript
困った事 - MovieClip の外部拡張クラスにて、 XML.onLoad() 実行時のコールバック関数定義の中でクラスメソッドをコールしたいものの、うまく実行できない。ターゲットパス参照もできない。どうすりゃいいのさ。
例1) XML.onLoad 内にてメソッド fuga が実行できない
class hoge1 extends MovieClip { function hoge1 (){ var xml:XML = new XML(); xml.onLoad = function(){ fuga(); // 実行できない } xml.load("test.xml"); } function fuga (){ trace("success"); } }
この時 fuga() は実際には this.fuga() を呼び出していて、XML.onLoad() 内の this は XMLオブジェクトを指している為、うまくいかないようです。また、ターゲットパス参照を使って this._parent.fuga() としても、XMLオブジェクトとクラス hoge1 は親子関係が定義されていない為、これもうまくいきません。
解決方法1
自分で思いついた対策。クラス自体を参照する変数を直前で用意してあげるとうまくいきます。
例2) this を別名変数に格納しておくとうまくいく
class hoge2 extends MovieClip { function hoge2 (){ var xml:XML = new XML(); var t = this; // クラス参照変数を作る xml.onLoad = function(){ t.fuga(); } xml.load("test.xml"); } function fuga (){ trace("success"); } }
fuga() は実際には this.fuga() つまり XML.fuga() を自動参照してるのに、変数 t は実際には this.t つまり XML.t とはならず、ちゃんと1階層上のスコープ変数を参照できている模様... ちょっと疑問な挙動ですが、おそらく(すげー適当な推測)、こんな「同スコープ内に存在しない場合は1階層上のスコープを見にいく」挙動は変数に対してのみ有効で、メソッドに対しては働かない機能なのかなあ。
解決方法2
WEBを調べて見つけた別の解決方法。FLASH-JP.COM のフォーラム中の
XML.onLoad()内において親オブジェクトを参照する方法
エントリにて 野中文雄 氏が提案していた解決方法です。あー、こっちの方が全然スマートな気がする。野中さんに感謝です。
例3) Delegate クラスを使ってスコープを変える
import mx.utils.Delegate; class hoge3 extends MovieClip { function hoge3() { var xml:XML = new XML(); xml.onLoad = Delegate.create(this, function(){ fuga(); }); xml.load("test.xml"); } function fuga() { trace("success"); } }
Delegate クラスについての詳細は FLASH ユーザーガイドか、野中氏の Macromedia Flash非公式テクニカルノート - イベントの委譲 の記事を参照してくださいませ。
- Newer: 聖なる予言 - 九つの知恵ダイジェスト
- Older: ターゲットパスの挙動をきちんと整理してみる part2