想要观察 Flex Compiler 生成的 ActionScript 很简单
只要添加编译参数 -keep-generated-actionscript=true
就可以在 /src/generated 下查找了
举例来说,想要仿真以下的 DataBinding Expression:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="#FFFFFF" layout="vertical" fontSize="12">
<mx:Label text="Binding Source:" />
<mx:HSlider id="slider1" snapInterval="1" maximum="100" value="50" />
<mx:Label text="Binding Destination:" />
<mx:HSlider id="slider2" snapInterval="1" maximum="100" value="{slider1.value}" />
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->
步骤有点多~~
-
实作 mx.binding.IBindingClient; 界面
-
汇入必要的 Class:
import mx.binding.*;
import mx.binding.utils.*;
import mx.core.mx_internal;
-
宣告 Bindings, Watchers 等属性:
mx_internal var _bindings : Array = [];
mx_internal var _watchers : Array = [];
mx_internal var _bindingsByDestination : Object = {};
mx_internal var _bindingsBeginWithWord : Object = {};
-
创建 Bindings 与 Watchers:
mx_internal::_bindings[0] = new Binding(this,
function():* {return slider1.value;},
function(sourceReturnValue:*):void {slider2.value = sourceReturnValue;},
"slider2.value");
mx_internal::_watchers[0] = new PropertyWatcher("slider1",
{propertyChange: true},
[mx_internal::_bindings[0]],
function(propertyName:String):* { return this[propertyName]; });
mx_internal::_watchers[1] = new PropertyWatcher("value",
{valueCommit: true, change: true},
[mx_internal::_bindings[0]], null);
mx_internal::_watchers[0].updateParent(this);
mx_internal::_watchers[0].addChild(mx_internal::_watchers[1]);
mx_internal::_bindings[0].execute();
最后一个步骤看起来就有点复杂了
Binding 的功能有点类似 Event Handler,负责运行 DataBinding 运算
而 Watcher 则是类似 Event Listener,负责监听资料来源的变化
为什么不用标准的 Event Listener 机制
看 Flex Source 上写的是因为效能考量
先看一下 mx.binding.Binding 类别的使用方式
public function Binding(document:Object, srcFunc:Function, destFunc:Function, destString:String)
- document: binding 目标的文档
- srcFunc: 用来取值的函式
- destFunc: 将值指定到目的地的函式
- destString: 用来告诉 ValidationManager 验证该字段
至于 Watcher 其实只是一个上层类别
实际使用时,需要视 Binding Source 种类决定使用哪一种子 Watcher
XMLWatcher, PropertyWatcher, StaticPropertyWatcher, RepeaterItemWatcher, RepeaterComponentWatcher,
FunctionReturnWatcher, ArrayElementWatcher
Watcher 有一个最特别的地方是,它具有父子关系
上层的父 Watcher 会触发下层的子 Watcher 对象
可以藉由以下 Watcher 函式设置:
public function updateParent(parent:Object):void;
public function addChild(child:Watcher):void;
public function removeChildren(startingIndex:int):void;
public function updateChildren():void;
综合上述的步骤
完整手工设置的 DataBinding MXML 程序码如下:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundColor="#FFFFFF" layout="vertical" fontSize="12"
implements="mx.binding.IBindingClient"
creationComplete="onCreateComplete();">
<mx:Script>
<![CDATA[
import mx.binding.*;
import mx.binding.utils.*;
import mx.core.mx_internal;
mx_internal var _bindings : Array = [];
mx_internal var _watchers : Array = [];
mx_internal var _bindingsByDestination : Object = {};
mx_internal var _bindingsBeginWithWord : Object = {};
public function onCreateComplete():void{
mx_internal::_bindings[0] = new Binding(this,
function():* {return slider1.value;},
function(sourceReturnValue:*):void {slider2.value = sourceReturnValue;},
"slider2.value");
// mx_internal::_bindings[0].mx_internal::isEnabled = false;
mx_internal::_watchers[0] = new PropertyWatcher("slider1",
{propertyChange: true},
[mx_internal::_bindings[0]],
function(propertyName:String):* { return this[propertyName]; });
mx_internal::_watchers[1] = new PropertyWatcher("value",
{valueCommit: true, change: true},
[mx_internal::_bindings[0]], null);
mx_internal::_watchers[0].updateParent(this);
mx_internal::_watchers[0].addChild(mx_internal::_watchers[1]);
mx_internal::_bindings[0].execute();
// BindingManager.debugBinding("slider2.value");
}
]]>
</mx:Script>
<mx:Label text="Binding Source:" />
<mx:HSlider id="slider1" snapInterval="1" maximum="100" value="50" />
<mx:Label text="Binding Destination:" />
<mx:HSlider id="slider2" snapInterval="1" maximum="100" />
</mx:Application>
<!-- Ticore's Blog - http://ticore.blogspot.com/ -->
相关连结:
Flex 技巧 - 将资料绑定封装起来
Flex 技巧 - BindingManager 使用方式
Flex 技巧 - 观察 Data Binding 资料变化
Flex Tip - 在 Data Binding 内使用 [...] 运算子
Flex 2 Bindable Metadata Tag 背后实际作用
Flex 2.0 - 以 ActionScript 3.0 动态设置 Data Binding
Soph-Ware Associates Blog - Data Binding in Flex, Part I
Soph-Ware Associates Blog - Data Binding in Flex, Part II