Flex Bindableの使い方
4300 ワード
メタデータ(metadata):[Bindable]とは、Flexで最も多く使われているメタデータのことです.
まず、メタデータは文法の一部ではなく、コンパイラに専門的に使われていることを理解しなければなりません.はっきり言って、コンパイラに何かを教えたり、javaを学んだりしたことがあることを知っておくべきです.Bindableにとって、その役割はflexコンパイラに、いくつかのものにバインド関係を確立することを教えることであり、flexコンパイラはコンパイル中にAS(flexコンパイラはmxmlをasにコンパイルし、swfにコンパイルし、swfを直接コンパイルすることもできる.純粋なas 3コードで書けば実現できますが、奥さんが面倒です.バインドとは何か:例を挙げると、次のpublic変数に[Bindable][Bindable]public var name:String=""";public変数としては,必ず値を付与してもよいし,他の変数に値を付与してもよい.バインドの役割は、nameが変更されると(割り当てられた)、nameの影響(割り当てられた)他の変数に変更が通知される可能性があることです.ここでの「可能性」はコンパイラが判断する必要があります.これがメタデータがコンパイラに使われている理由です.mxmlで{}の構文を使うところがバインドされたオブジェクトであり,例えばlabel={xxx.name}であり,nameが変化するとlabelも変化する.このように,我々はnameの値を簡単に変えただけで,バインドがあるため,インタフェース上のlabelも自動的に変化したので,爽やかであろう.クラス、変数、getter/setterの3つの場所で使用できます.publicかどうかは関係ないが、privateのは自分で使うしかないだろう.Classではすべてのpublicプロパティ(変数、getter/setter、一般メソッドを含む)に[Bindable]を付けるのが簡単ですが、一般的なメソッドでは[Bindable]は使えません.変数は上に述べたように、簡単に省略します.読み取り専用で、属性(getter/setter)だけを書く上でやっと肝心なところを話しました.getterとsetterは方法に似ているので、使うと少し違います.この例を見てみましょう.
元の想定はcontentバインド_wholeTextですが、動作しません.どうして?wholeTextは複雑すぎて、コンパイラに「可能」から除外され、コンパイラはバインド関係がないと考えていますが、簡単なreturn contentであれば、可能です.私はここで権威的な解釈をいくつか見つけた.http://www.rubenswieringa.com/blog/binding-read-only-accessors-in-flexからEly Greenfieldを見つけて話した.Now keep in mind that there's no way for the compiler to actually tell if the value of a property get function would be different if called, short of doing an extensive code flow analysis of the get function, identifying all the inputs that might be affecting the value of the get function (i.e., member fields, statics, globals that are used in the get function and in any methods, global functions, closures, etc) it might call, and setting up watchers on every one of those to trigger the binding when any of them change. That's prohibitively difficult, and expensive to do. So the compiler doesn't try. Instead when you put [Bindable] on a get/set property, the compiler makes it bindable with a little creative rewriting that allows the framework to watch the get function, and dispatch a change event when the get function is triggered. This means that automatic bindable properties don't work when the get function is computed from multiple values, or when you change its value by setting a backing field, rather than using the set function. It _also_ means that if you have no set function, we can pretty much guarantee that there's no way automatically bindable get properties will be triggered. a read only propeerty is, to the compiler, completely opaque…at the moment, it has no idea where that value is coming from, and hEnce will never be able to‘automatically’trigger the binding.はっきり言って複雑さを低減し効率を高めるために複雑な場合のgetterは無視されます.どのように解決しますか?手動でバインドを確立することができます.すなわち[Bindable(「eventName」)コードをこのように変更します.
これにより、コンパイラが自動的に認識することを回避します.自分でバインド関係を加えると、_contentが付与され、_contentChangedイベントが発行され、バインドされたgetterメソッドがすべて実行されることを通知します.これは、バインドがイベントゲームにすぎず、flexがユーザーに多くの下位アルゴリズムを隠していることを示しています.
まず、メタデータは文法の一部ではなく、コンパイラに専門的に使われていることを理解しなければなりません.はっきり言って、コンパイラに何かを教えたり、javaを学んだりしたことがあることを知っておくべきです.Bindableにとって、その役割はflexコンパイラに、いくつかのものにバインド関係を確立することを教えることであり、flexコンパイラはコンパイル中にAS(flexコンパイラはmxmlをasにコンパイルし、swfにコンパイルし、swfを直接コンパイルすることもできる.純粋なas 3コードで書けば実現できますが、奥さんが面倒です.バインドとは何か:例を挙げると、次のpublic変数に[Bindable][Bindable]public var name:String=""";public変数としては,必ず値を付与してもよいし,他の変数に値を付与してもよい.バインドの役割は、nameが変更されると(割り当てられた)、nameの影響(割り当てられた)他の変数に変更が通知される可能性があることです.ここでの「可能性」はコンパイラが判断する必要があります.これがメタデータがコンパイラに使われている理由です.mxmlで{}の構文を使うところがバインドされたオブジェクトであり,例えばlabel={xxx.name}であり,nameが変化するとlabelも変化する.このように,我々はnameの値を簡単に変えただけで,バインドがあるため,インタフェース上のlabelも自動的に変化したので,爽やかであろう.クラス、変数、getter/setterの3つの場所で使用できます.publicかどうかは関係ないが、privateのは自分で使うしかないだろう.Classではすべてのpublicプロパティ(変数、getter/setter、一般メソッドを含む)に[Bindable]を付けるのが簡単ですが、一般的なメソッドでは[Bindable]は使えません.変数は上に述べたように、簡単に省略します.読み取り専用で、属性(getter/setter)だけを書く上でやっと肝心なところを話しました.getterとsetterは方法に似ているので、使うと少し違います.この例を見てみましょう.
[Bindable]
private var content:Array = new Array();
[Bindable]
public function set _content(ct:String):void
{
content = ct.split(SEP);
}
[Bindable]
public function get _wholeText():String
{
if(content.length == 0)
{
return "";
}
else
{
var _w:String = "";
for(var i:int=0 ; i<content.length ; i++)
{
_w += content[i] + "\r
";
}
return _w;
}
}
元の想定はcontentバインド_wholeTextですが、動作しません.どうして?wholeTextは複雑すぎて、コンパイラに「可能」から除外され、コンパイラはバインド関係がないと考えていますが、簡単なreturn contentであれば、可能です.私はここで権威的な解釈をいくつか見つけた.http://www.rubenswieringa.com/blog/binding-read-only-accessors-in-flexからEly Greenfieldを見つけて話した.Now keep in mind that there's no way for the compiler to actually tell if the value of a property get function would be different if called, short of doing an extensive code flow analysis of the get function, identifying all the inputs that might be affecting the value of the get function (i.e., member fields, statics, globals that are used in the get function and in any methods, global functions, closures, etc) it might call, and setting up watchers on every one of those to trigger the binding when any of them change. That's prohibitively difficult, and expensive to do. So the compiler doesn't try. Instead when you put [Bindable] on a get/set property, the compiler makes it bindable with a little creative rewriting that allows the framework to watch the get function, and dispatch a change event when the get function is triggered. This means that automatic bindable properties don't work when the get function is computed from multiple values, or when you change its value by setting a backing field, rather than using the set function. It _also_ means that if you have no set function, we can pretty much guarantee that there's no way automatically bindable get properties will be triggered. a read only propeerty is, to the compiler, completely opaque…at the moment, it has no idea where that value is coming from, and hEnce will never be able to‘automatically’trigger the binding.はっきり言って複雑さを低減し効率を高めるために複雑な場合のgetterは無視されます.どのように解決しますか?手動でバインドを確立することができます.すなわち[Bindable(「eventName」)コードをこのように変更します.
[Bindable]
private var content:Array = new Array();
[Bindable]
public function set _content(ct:String):void
{
content = ct.split(SEP);
this.dispatchEvent(new Event("_contectChanged"));
}
[Bindable("_contectChanged")]
public function get _wholeText():String
{
if(content.length == 0)
{
return "";
}
else
{
var _w:String = "";
for(var i:int=0 ; i<content.length ; i++)
{
_w += content[i] + "\r
";
}
return _w;
}
}
これにより、コンパイラが自動的に認識することを回避します.自分でバインド関係を加えると、_contentが付与され、_contentChangedイベントが発行され、バインドされたgetterメソッドがすべて実行されることを通知します.これは、バインドがイベントゲームにすぎず、flexがユーザーに多くの下位アルゴリズムを隠していることを示しています.