主要功能如下:
1.代理另一個物件的所有屬性(無法區分唯讀、唯寫)和方法。
2.若被代理物件發出這個Proxy有偵聽的事件,一律使用Event.clone轉發。
3.使用$alias產生屬性及方法的別名。
注意事項:
1.for...in迴圈,只會跑這個Proxy上的屬性及方法(含別名),不會有被代理者的。
2.若被代理者的屬性、方法名和Proxy擁有的同名,Proxy的屬性及方法優先。
3.動態加入的屬性方法,不會加到被代理者身上。
4.$super(被代理者)的更換,不會影響Proxy現有的屬性、方法。已加到Proxy上的事件偵聽式也不會消失。
AdvancedProxy
package tw.right929.proxy
{
import flash.events.*;
import flash.utils.*;
import tw.right929.event.AdvancedEventDispatcher;
use namespace flash_proxy
/**
* 這個物件是動態的,可以完全代理另一個物件。
* 主要功能如下:
* 1.代理另一個物件的所有屬性(無法區分唯讀、唯寫)和方法。
* 2.若被代理物件發出這個Proxy有偵聽的事件,一律使用Event.clone轉發。
* 3.使用$alias產生屬性及方法的別名。
* 注意事項:
* 1.for...in迴圈,只會跑這個Proxy上的屬性及方法(含別名),不會有被代理者的。
* 2.若被代理者的屬性、方法名和Proxy擁有的同名,Proxy的屬性及方法優先。
* 3.動態加入的屬性方法,不會加到被代理者身上。
* 4.$super(被代理者)的更換,不會影響Proxy現有的屬性、方法。已加到Proxy上的事件偵聽式也不會消失。
*/
public dynamic class AdvancedProxy extends Proxy implements IEventDispatcher
{
private var _propertyMap:Object = new Object();
private var _aliasMap:Object = new Object();
private var _$super:*;
private var _properties:Array = new Array();
private var _needUpdateProperties:Boolean = false;
private var _eventDispatcher:AdvancedEventDispatcher;
public function AdvancedProxy()
{
super();
_eventDispatcher = new AdvancedEventDispatcher(this);
}
/**
* 設定被代理的物件,會連事件也一併代理(僅轉發)。
*/
public function get $super():*
{
return _$super;
}
public function set $super(v:*):void
{
if(_$super == v)
return;
_$super = v;
_eventDispatcher.eventSource = _$super;
}
/**
* 幫屬性及方法增加別名。
* 原先的方法名不會消失,別名僅是轉發。
* 若別名已存在,會蓋掉舊的別名。
* 別名會出現在for...in的迴圈之中。
* 刪除別名一樣使用delete的方法。
*/
public function $alias(name:String , alias:String):void
{
_aliasMap[alias] = name;
}
/**
* 傳入一個名字判斷是不是別名。
*/
public function $isAlias(name:*):Boolean
{
if(name is QName)
name = name.localName;
if(_aliasMap[name])
return true;
return false;
}
private function getRealName(name:*):*
{
if(name is QName)
name = name.localName;
if(_aliasMap.hasOwnProperty(name))
return _aliasMap[name];
return name;
}
override flash_proxy function setProperty(name:*, value:*):void
{
name = getRealName(name);
if(this[name] == value)
return;
_needUpdateProperties = true;
if(_hasProperty(name))
_propertyMap[name] = value;
else if(_$super && _$super.hasOwnProperty(name))
_$super[name] = value;
else
_propertyMap[name] = value;
}
override flash_proxy function deleteProperty(name:*):Boolean
{
_needUpdateProperties = true;
if($isAlias(name))
return delete _aliasMap[name];
return delete _propertyMap[name];
}
override flash_proxy function callProperty(name:*, ... rest):*
{
name = getRealName(name);
if(_hasProperty(name))
return _propertyMap[name].apply(this , rest);
else if(_$super)
return _$super[name].apply(this , rest);
}
override flash_proxy function getProperty(name:*):*
{
name = getRealName(name);
if(_hasProperty(name))
return _propertyMap[name];
else if(_$super)
return _$super[name];
}
override flash_proxy function nextName(index:int):String
{
updateProperties();
return _properties[index-1].toString();
}
override flash_proxy function nextNameIndex(index:int):int
{
updateProperties()
if (index < _properties.length)
return index + 1;
else
return 0;
}
override flash_proxy function nextValue(index:int):*
{
updateProperties();
if($isAlias(_properties[index-1]))
return _aliasMap[_properties[index-1]];
else
return _propertyMap[_properties[index-1]];
}
override flash_proxy function hasProperty(name:*):Boolean
{
if(_hasProperty(name))
return true;
else if(_$super && _$super.hasOwnProperty(name))
return true;
else
return false;
}
/**
* 尋找是否有這個屬性,含別名。
*/
private function _hasProperty(name:*):Boolean
{
if(name is QName)
name = name.localName;
if(name in _propertyMap)
return true;
if(name in _aliasMap)
return true;
return false;
}
/**
* 重整自已的屬性清單,含別名。
*/
private function updateProperties():void
{
if(_needUpdateProperties)
{
_properties = new Array();
for (var p:String in _propertyMap)
_properties.push(p);
for (var a:String in _aliasMap)
_properties.push(a);
_needUpdateProperties = false;
}
}
public final function addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
{
_eventDispatcher.addEventListener(type , listener , useCapture , priority , useWeakReference);
}
public final function removeEventListener(type:String, listener:Function, useCapture:Boolean=false):void
{
_eventDispatcher.addEventListener(type , listener , useCapture);
}
public final function dispatchEvent(event:Event):Boolean
{
return _eventDispatcher.dispatchEvent(event);
}
public final function hasEventListener(type:String):Boolean
{
return _eventDispatcher.hasEventListener(type);
}
public final function willTrigger(type:String):Boolean
{
return _eventDispatcher.willTrigger(type);
}
public final function getAllEventListenerType():Array
{
return _eventDispatcher.getAllEventListenerType();
}
public final function removeAllEventListener():void
{
_eventDispatcher.removeAllEventListener();
}
public final function removeEventListenerByType(type:String):Array
{
return _eventDispatcher.removeEventListenerByType(type);
}
public final function addEventListenerByArray(listeners:Array):void
{
_eventDispatcher.addEventListenerByArray(listeners);
}
}
}
測試<?xml version="1.0" encoding="utf-8"?>
<s:Application creationComplete="init()" xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768">
<fx:Script>
<![CDATA[
import tw.right929.proxy.AdvancedProxy;
private function init():void
{
var arr:Array = [0 , 1];
var arrProxy:AdvancedProxy = new AdvancedProxy();
arrProxy.$super = arr;
arrProxy.push(2,3);
trace(arr);//0,1,2,3
arrProxy.$alias("push" , "addChild");
arrProxy.addChild(4,5);
trace(arr);//0,1,2,3,4,5
delete arrProxy["addChild"];
var s:Sprite = new Sprite();
arrProxy.$super = s;
arrProxy.addEventListener("E" , onE);
s.dispatchEvent(new Event("E"));//onE
}
private function onE(e:Event):void
{
trace("onE");
}
]]>
</fx:Script>
</s:Application>
這個類別是從AdvancedObject中抽出來的,AdvancedObject也需要改寫。
沒有留言:
張貼留言