2011-01-12 3 views
2

私は、Action Scriptがxmlに続き、その中からDisplayObject階層を構築するファクトリを取得しました。これは、スクリプトがxmlでどの要素が遭遇するかを事前に知らないため、必要なユーザ定義のファクトリクラスを知らないことを意味します。アクションスクリプト3でユーザ定義クラスのインスタンスを動的に作成することはできますか?

は、私はこのような何かをすることが可能であることを知っている:

var rect:*, className:String = "flash.geom.Rectangle"; 

if (ApplicationDomain.currentDomain.hasDefinition(className)) {   
    rect = new(getDefinitionByName(className)); 
} 

そして長方形インスタンスがインスタンス化されます。しかし、flash.geom.Rectanglemy.factory.Blockのように置き換えるとすぐに機能しなくなり、条件付きでコメントアウトすると簡単になります。"変数ブロックが定義されていません"エラー。

明白な問題を回避するには、前工場を活性化する、my.factory.Block(および他のすべてのコンポーネント)のインスタンスを作成することであろうが、それはちょっと動的コンポーネント工場の全体のポイントを台無し。

もちろん私には:import my.factory。*;文がスクリプトの先頭に表示されます。

もっとスマートな解決方法はありますか?

答えて

3

他の人が指摘しているように、問題はおそらくコンパイルされたswfに含まれていないクラスの問題です。ダニエルが指摘したように、インポートは十分ではありません。クラスへの参照が必要です。しかし、変数を宣言する必要はありません。ケイ先生が述べたように、次のようにすることができます:

MyClass;

mxmlcを使用してコンパイルする場合は、-includesオプションを使用して、強制的にコンパイルされたswfに含めるクラスを指定できます。これについての良い点は、コード内に参照を持つ必要がないことです。あなたが含めたいクラスの本当に大きなパッケージを持っていますが、クラス名を書きたくない場合は

-includes com.example.MyClass com.example.MyOtherClass

:それはこのようになりますすべてのクラスについて、compcを使用してパッケージをswcとしてコンパイルし、mxmlcの-include-librariesオプションを使用してパッケージ全体を組み込むことができます。

+0

私はMyClassと思います。最も便利で短い方法です。ところで、誰もここでそれを言及しませんでしたが、私は試してみました。クラスプロパティのセクションであっても、どこでもコンストラクタ本体から「動的に」ロードするクラスを参照できるようです。 – jayarjo

+0

はい、良い点です。リファレンスがどこにあるかは関係ありません。 – Joony

2

私はApplicationDomain.currentDomain.hasDefinition(className)を一度も使ったことがありません。代わりに、これを実行するtry catchの方法を使っていますが、これを行うより良い方法です。だからこそ、ありがとう。

とにかく、前に同じ問題が出てきました。問題は、コンパイラがすべてのmy.factory.*;アセットをコンパイルしないことです。私がやったことは、私が必要とする各オブジェクトのダミーインスタンスを作成することです。

privete function uncalledFunction():void{ 
    var s_01:Block; 
    var s_02:Triangle; 
    var s_03:Pineapple; 
} 

この「それをだまし」私のために働いたが、私は任意のよりエレガントな解決策があるかどうかを確認するために興味を持っていました。

2

私はダニエルの応答に似た何かをやったが、あなたもそれはこれで十分です...変数を宣言する必要はありません。

Block; Triangle; Pineapple; 
+0

私は投票人を好きではないので、私はしませんが、あなたは完全にその点を見逃しました。 – jayarjo

+0

Cay、実際にSWFにクラスを含めるためにDanielが投稿したものの代わりにこれを表示していますか? – mpdonadio

+0

Cayさんの言うとおり、すべての 'var s_01:Block;'でvarを宣言する必要はありません。クラスにクラスへの参照があるため、クラスをコンパイラに強制的に組み込むことができます。 'Block;'があれば十分ですが、import文を使うのは十分ではありません。 – Daniel

2

その他のソリューションを提供するが、ここでの説明できました何が起こっている。

importステートメントは、コンパイル時に実際にクラスコードを含みません。基本的に型シグネチャをスコープに入れて、コンパイラがbarfを持たないようにします。 http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/statements.html#import

から

読み込んだクラスがスクリプトでそれを使用しない場合、クラスはSWFファイルの一部としてエクスポートされません。つまり、SWFファイルのサイズを気にせずに大きなパッケージをインポートすることができます。クラスに関連付けられたバイトコードは、そのクラスが実際に使用されている場合にのみSWFファイルに含まれます。必要のないクラスをインポートすることの1つの欠点は、名前の衝突の可能性を増やすことです。

ここに示した解決法は、クラスをSWFに取り込むためのメソッドを提供します。

編集:

OK、私はもっと自分の元の質問を理解すると思います。クラスコードはどこかから来なければなりません。提示されたメソッドの1つを使用してリンクするか、またはクラスを子SWFに配置し、クラス名を取得するロジックを更新し、適切な子SWFをロードしてクラス定義を取得する必要があります今ロードしたSWFのApplicationDomain。

+0

swfに暗黙的に定義されたクラスを含めることができるimport文の特殊な形式があると思います。好き!最後か何かのシンボル。 – jayarjo

0

ここに私が一緒に投げたコードがあります。私はタイムラインで試してみました。それはあなたが望むものですか?

import flash.system.ApplicationDomain; 

trace(makeInstance("flash.display.Sprite")); //[object Sprite] 
trace(makeInstance("flash.geom.Rectangle")); //(x=0, y=0, w=0, h=0) 
trace(makeInstance("hi.there")); //null 

function makeInstance(className : String) : * 
{ 
    var MyClass:Class; 
    var instance : * = null; 

    if (! ApplicationDomain.currentDomain.hasDefinition(className)) return null; 

    MyClass = getDefinitionByName(className) as Class; 
    return new MyClass(); 
} 
+0

こんにちは。何かをするあなた自身のパッケージがあると想像してください。私は、コードを「複雑すぎる」ことなく無害にインスタンスを作成する方法を探していました。そうです。それは私が望んでいたものではありません:) – jayarjo

関連する問題