Delegate委托事件和Proxy类

2006-03-22 00:16:35

前今天在写一个类的时候,遇到了一个问题,我在类中对XML文件进行解析,在解析结束之后调用特定的事件.但是我失败了.大家可以看看我的类是这样的: |class com.flashpixy.Test |{ | var xmlPath : String; | function GlideWin (xml:String) | { | xmlPath = xml; | init (); | } | private function init () | { | var doc:XML = new XML(); | doc.load (xmlPath); | doc.ignoreWhite = true; | doc.onLoad = loadHandler; | } | private function loadHandler(ok) | { | if (ok) | { | testFun(); | } else | { | trace("xml document is not found"); | } | } | private function testFun () | { | trace ("welcome!"); | } |} 在这里面我打算在init()函数中对XML进行解析,然后再执行testFun这个方法,但是XML文件是可以解析的,就是不执行testFun (),这是什么原因呢?原来是他们的作用范围的问题,在XML解析的过程中在onLoad函数中调用不到Test类中的testFun这个函数.那么我们可以怎么作呢?当然是有办法的. 我们可以使用Delegate类,它可以将事件委托给特定的范围和函数.如果你使用的是Flash 2004的话,那么你要升级到7.2版本,这样你就可以直接的使用mx.util.Delegate了, [url=http://www.macromedia.com/support/flash/downloads.html][升级文件下载地址][/url] ---------------------------------------------------------------- 具体的使用方法可以参看下面的文章,写的不错,原文为英文,我就在这里献丑,作下简单的翻译吧![url=http://www.person13.com/articles/proxy/Proxy.htm][英文地址][/url] 下面我们以这个例子对这个类使用进行简单的介绍: class SomeClass { private var _sProperty : String; public function SomeClass (sURL : String) { var lvInstance : LoadVars = new LoadVars (); lvInstance.onData = function (sText : String) : Void { // The following won't work because _sProperty is not defined within the lvInstance scope. _sProperty = sText; }; lvInstance.load (sURL); } } 其实这个类的情况和我上面遇到的情况是一样的.其实有很多的方法可以解决这个问题,但是MM提供了比较好的解决方法就是运用Delegate类,你可以使用Delegate.create来生成一个委托函数,来调用特定范围内的函数,例如: import mx.util.Delegate; class SomeClass { private var _sProperty : String; public function SomeClass (sURL : String) { var lvInstance : LoadVars = new LoadVars (); // Tell Flash to call the assignText( ) method using this as the scope. lvInstance.onData = Delegate.create (this, assignText); lvInstance.load (sURL); } // Since the assignText( ) method is called with the this scope, _sProperty is defined. private function assignText (sText : String) : Void { _sProperty = sText; } } 恩,不错,看起来很完美,但是在某些情况下就有点力不从心了.但是如果你想传递一些参数进去就有点问题了,不过也没有太大的关系,只是做法不是很地道罢了,我们可以把函数作为对象来看待,给函数负上属性值,然后通过arguments.caller来取得我们传递的参数,例如: class SomeClass { private var _sProperty : String; public function SomeClass (sURL : String) { var lvInstance : LoadVars = new LoadVars (); // Make the function. var fDelegateFunction : Function = mx.utils.Delegate.create (this, assignText); // Assign a custom property to the function object. fDelegateFunction.customProperty = "some property value"; // Assign the function to the onData event handler. lvInstance.onData = fDelegateFunction; lvInstance.load (sURL); } private function assignText (sText : String) : Void { _sProperty = sText; // Use arguments.caller to reference the proxy function to which the property was added. trace (arguments.caller.customProperty); } } 如果能够在调用create()的时候,一起传递参数就好了,但是Delegate显然是不能满足我们的要求的.没有关系,我们可以使用ascb.util.Proxy类来应对这个问题. [url=http://www.person13.com/articles/proxy/Proxy.htm][本类的下载地址][/url] [本站镜像] 大家可以看看下面的例子: class SomeClass { private var _sProperty : String; public function SomeClass (sURL : String) { var lvInstance : LoadVars = new LoadVars (); // The syntax for ascb.utils.Proxy.create( ) is similar to that of Delegate.create( ). // However, you can also specify additional parameters to pass along to the method. lvInstance.onData = ascb.utils.Proxy.create (this, assignText, "some property value"); lvInstance.load (sURL); } private function assignText (sText : String, sAnotherParameter : String) : Void { _sProperty = sText; // Much simpler. trace (sAnotherParameter); } } >>似乎这样完美了许多啊!在原文中还有一个例子,大家可以参考着学习一下.可惜我的英语太差啊,要是好的话,真是希望能找到更多更好的文章给大家.