FLEX 数据绑定专题(3)
2009年12月21日 星期一 01:55 P.M.
4. 使用Bindable 元数据标记 当属性成为数据绑定表达式源时,Flex 在源属性发生变化时自动将源属性的值拷贝给目的 属性。为了告知Flex 去执行这个拷贝工作,必须用[Bindable]元数据标记将这个属性注册到 Flex 中,并且源属性必须发出一个事件。 [Bindable] 元数据标记语法如下: [Bindable] [Bindable(event="eventname")] 如果忽略事件名称,Flex 会自动创建一个名为propertyChange,类型为 PropertyChangeEvent 的事件。 可以在三个地方使用[Bindable]元数据标记: 1. 在public 类定义之前使用。 在这个地方使用[Bindable]元数据标记使得类中定义的全部public 变量以及同时具 有setter 和getter 方法的public 属性能成为数据绑定表达式的源。这种情况下, [Bindable]不使用任何参数,如下例所示: [Bindable] public class TextAreaFontControl extends TextArea {} Flex 编译器自动为所有public 属性生成名为propertyChange,类型为 PropertyChangeEvent 的事件,以使这些属性可以被用于数据绑定表达式的源。 如果对属性进行写操作的时候属性值保持不变,Flex 不会发出事件或者更新属 性,这里判断属性是否不同可以翻译为如下的检测语句: (oldValue !== value) 这意味着,如果属性包含了一个对象引用,并且引用被更改为引用了一个不同但 是等价的对象,那么绑定也会被触发。如果属性没有被改变,而它所指向的对象在 内部发生了变化,那么绑定不会被触发。 注意:在public class 定义之前使用[Bindable]元数据标记只是将绑定作用于 public 属性,它不会作用于private 和protected 属性以及那些定义在其他 namespace 中的属性。必须在非public 属性前插入[Bindable]元数据标记,才能使 之成为数据绑定表达式的源。 2. 在public,protected 或者private 属性之前使用该标记可以将这个特定的属性定 义为支持数据绑定,标记可以有以下的形式: [Bindable] public var foo:String; Flex 编译器自动为那个属性产生名为propertyChange,类型为PropertyChangeEvent 的事件,如果写入的属性值不变,Flex 不会发出事件或者更新属性。也可以在 [Bindable]元数据标记中指定事件名,如下的例子所示: [Bindable(event="fooChanged")] public var foo:String; 这种情况下,开发者要自己负责产生和发出事件,通常在类的其他方法中完成 这些工作。尽管在类的级别上指定了[Bindable]标记,如果想要为事件命名,仍然 可以在[Bindable]中包含指定名称的事件。 3. 在由getter 或者setter 方法所定义的public,protected 或者private 属性之前 使用该标记。这种情况下,要想使用[Bindable]标记必须为属性同时定义setter 和 getter 方法。如果只是定义了一个setter 方法,那么你就创建了一个“只写”属性, 这样的属性不能作为数据绑定表达式的源。如果只定义getter 方法,那么就创建了 一个“只读”属性,把只读属性当作数据绑定源而不插入[Bindable]标记,就如同 使用了一个用const 关键字定义的变量来作为数据绑定表达式的源。(这样的绑定 源只能在应用启动时触发绑定一次,以后就不会再触发)。 这个标记可以由下面的形式定义: [Bindable] public function set shortNames(val:Boolean):void { ... } public function get shortNames():Boolean { ... } Flex 编译器自动为这个属性产生一个名为propertyChange,类型为 PropertyChangeEvent 的事件。如果属性值在写入的时候保持不变,Flex 不会发出 事件或者更新属性。为了确定属性是否变化,Flex 调用getter 方法来获取属性的当 前值。 也可以为事件指定名称,如下例所示: [Bindable(event="changeShortNames")] public function set shortNames(val:Boolean):void { ... // Create and dispatch event. dispatchEvent(new Event("changeShortNames")); } // Get method. public function get shortNames():Boolean { ... } 这种情况下,开发者要负责生成和发出事件。通常是在setter 方法中完成这个工作。 并且Flex 不会检查旧值和新值是否不同。尽管在类的级别上指定了[Bindable]标记,如果 想要为事件命名,仍然可以在[Bindable]中包含指定名称的事件。 下面的代码使以变量形式定义的maxFontSize 和minFontSize 属性可以作为数据绑定的 源: // Define public vars for tracking font size. [Bindable] public var maxFontSize:Number = 15; [Bindable] public var minFontSize:Number = 5; 在下面的例子中,使setter 和getter 方法形式定义的public 属性成为数据绑定的源。 [Bindable]元数据标记中引入了属性变化时由setter 方法发出的事件: // Define private variable. private var _maxFontSize:Number = 15; [Bindable(event="maxFontSizeChanged")] // Define public getter method. public function get maxFontSize():Number { return _maxFontSize; } // Define public setter method. public function set maxFontSize(value:Number):void { if (value <= 30) { _maxFontSize = value; } else _maxFontSize = 30; // Create event object. var eventObj:Event = new Event("maxFontSizeChanged"); dispatchEvent(eventObj); } 在这个例子中,setter 更新了属性的值,然后创建并发出了一个事件来激发对数据绑定目的 属性的更新。 在MXML 文件中,通过在<mx:Metadata>块中引入[Bindable]元数据标记,就可以将所有以变量 形式定义的public 属性成为数据绑定的源,例子如下: <mx:Metadata> [Bindable] </mx:Metadata> 在<mx:Script>块中也可以在使用[Bindable]元数据标记使单个的变量形式定义的属性成 为数据绑定表达式的源。另外,也可以对setter 及getter 方法定义的属性使用[Bindable]元 数据标记,使之成为数据绑定表达式的源。 将只读属性作为数据绑定的源 使用getter 方法而没有setter 就可以自动定义一个只读属性作为数据绑定表达式的源。 Flex 只在应用启动时执行一次数据绑定。因为来自于只读属性的数据绑定只在应用启动时发生 一次,所以可以对只读属性省略[Bindable]元数据标记。 用静态属性作为数据绑定源 可以将静态属性作为数据绑定表达式的源,Flex 在应用启动时执行一次数据绑定,然后在 静态属性发生变化的时候再执行数据绑定。 可以将静态常量自动作为数据绑定表达式的源,Flex 只在应用启动时执行一次数据绑定。因 为数据绑定只在应用启东时发生一次,所以可以对静态常量省略[Bindable]元数据标记。下面 例子使用静态常量作为数据绑定表达式的源。 <?xml version="1.0"?> <!-- binding/StaticBinding.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ // This syntax casues a compiler error. // [Bindable] // public static var varString:String="A static var."; public static const constString:String="A static const."; ]]> </mx:Script> <!-- This binding occurs once at application startup. --> <mx:Button label="{constString}"/> </mx:Application> 使用可绑定属性链进行工作 当指定一个属性作为数据绑定表达式的源时,Flex 不仅监控这个属性的变化,也会监控这 个由这个属性作为开始点的属性链的变化。整个属性链,包括源属性,被称为“可绑定的属性 链”。在下面的例子中,firstName.text 是一个可绑定的属性链: <mx:Text id="myText" text="{firstName.text}"/> 开发者可以使用很长的属性链,如下例所示: <mx:Text id="myText" text="{user.name.firstName.text}"/> 只有当text 属性是可绑定的,数据绑定机制才能检查text 属性的变化。但是,如果在运 行时,想要向属性链中的部分属性赋予新值,那么属性链中的每个属性都必须是可绑定的,才 能使数据绑定机制起作用。否则,在运行时更改user,name 或者firstName 属性会导致数据绑 定机制无法检查text 属性的变化。 在使用BindingUtils.bindProperty()或者BindingUtils.bindSetter()方法时,可以将可 绑定的属性链作为方法的参数,例如,bindProperty()方法有以下的声明: public static function bindProperty(site:Object, prop:String, host:Object, chain:Object, commitOnly:Boolean = false):ChangeWatcher Host 和chain 属性指定了数据绑定表达式的源。使用bindProperty()方法可以定义一个 数据绑定表达式,如下: bindProperty(myText, 'text', user, ["name","firstName","text"]); 这个例子中,["name","firstName","text"]定义了相对于user 对象的可绑定属性链。注 意,在本例中,user 不是可绑定属性链的一部分。 在MXML 数据绑定表达式中,可绑定属性连总是相对于this。因此,要想定义一个同上面的 MXML 等价的数据绑定表达式,应按如下例子使用bindProperty()方法: bindProperty(myText, 'text', this, ["user", "name","firstName","text"]); |