Delegate class委派类的应用

Delegate(委派) 类是一个非常有用的类,由Mike Chambers编写,它可以使组件的事件应用更容易,这个类已经包含在”Ellipsis”中,也就是flashmx2004的升级版本中,在开始之前请先去下载升级版本flashmx2004updata_cn.exe,升级版本中包含有Delegate类,它使FLASH更加稳定,快速,更好。

通常情况下,你可能用两种方式来指定组件的事件类型,一种是使用addEventListener :指定事件给一个对象,一种是指事件定给一个函数。

指定事件给对象:
我们可以这样

代码:
var obj = new Object();
obj.click = function(evt)
{
        trace(evt.target);
        trace(this);
}
myBtn.addEventListener("click",obj);

指定事件给函数:

代码:
function myClickHander(evt){
    trace(evt.target);
    trace(this);
}
myBtn.addEventListener("click",myClickHander);

第一种方法的问题在于事件方法必须与事件同名(也说是上例中的click)。因此,如果你想指定几个组件事件给一同一个对象,你需要创建很笨而且冗长的条件语句。象这样:

代码:
obj = new Object();
obj.click = function(evt)
{
        if(evt.target == 'myBtn')
        {
                trace('first button');
        }
        if(evt.target == 'myBtn2')
        {
                trace('second button');
        }
}
myBtn.addEventListener("click",obj);
myBtn2.addEventListener("click",obj);

第二种方法的问题在于范围:“this”引用触发事件的组件,不管你的函数在哪里定义。因些如果你想指定几个事件给同一个函数,”this”所指的对象会在函数每次执行时都不同。与上面的情况非常相似,我们仍需要大量的条件语句。

Mike Chambers针对多个对象和不太好的范围问题提供了一流的解决方法,也就是Delegate 类。不需要直接设计侦听器,你可以指定一个delegate 定义来侦听事件,它会在正确的范围内调用真实的方法。下面展示通过一个按钮说时你如何来使用它。

代码:
import mx.utils.Delegate;
function myClickHandler(evt)
{
        trace(evt.target);
        trace(this);
}
myBtn.addEventListener("click", Delegate.create(this,myClickHandler));

注意:我们需要先导入delegate 类,位于mx.utils.Delegate,当需要指定事件句柄时,我们创建一个Delegate,指定范围和最终的事件句柄。Delegate类只是声明一个静态的对象,create,类似如下创建过程:

代码:
static function create(obj:Object, func:Function):Function

上面的代码中的obj是你想要指定给func函数的范围。如果你想要移除事件侦听,也是非常简单:如下:

代码:
import mx.utils.Delegate;
var md = Delegate.create(this, someFunction);
myBtn.addEventListener('click',md);
//其它动作
//然后移除
myBtn.removeEventListener('click',md);

如你所看到的,Delegate.create给你一个非常好和简单的方法来处理组件的事件。引用jess warden的话说:使用Delegate 可以使你变得更聪明!

Delegate也可以工作在除了组件之外的低级别事件中,例如,你可以使用movieclip’s onEnterFrame事件或一个xml对象的onLoad事件,如下:

代码:
import mx.utils.Delegate;

function xmlLoaded(success)
{
        trace(this);
        trace(success);
}

function handleEnterFrame()
{
        trace(this);
        trace(getTimer());
}

var myXML = new XML();
myXML.onLoad = Delegate.create(this, xmlLoaded);
myXML.load(“some.xml”);

//myMc为当前帧上一个影片剪辑
myMC.onEnterFrame = Delegate.create(this, handleEnterFrame);

通过使用Delegate结合低级别事件它可以让你很轻松的解决在调用中的范围问题,这意味着可以大量的减少使用_root.

另一个使用Delegate的技巧方法是与setInterval结合使用。中心是当在间隔一定时间不断调用函数时,范围有些时候不会被一直传递,因些trace(this);会显示为undefined.,你可以使用下面的代码方法解决这个问题。

代码:
import mx.utils.Delegate;

function traceThis()
{
        trace(this);
}

var myInt = setInterval(Delegate.create(this, traceThis), 1000);

它可以工作的很好,不管是在时间线上还在类的内部,意味着你不必使用原有setInterval的类型为string的第二调用,如果不理解请参看FLASH帮助。它是非常好的,因为原有的setinterval在实际应用中显得不是很可靠,而第一调用是不可动摇的。另外,第一调用可以被编译器检查因为它是对函数的引用而不是针对string字符串。

通过上面我们使用Delegate.crea
te和this做为第一参数,其它的99%的时间你需要的是怎么样去使用它。然而在一些环境中你可以将Delegatey应用在其它内容上而不光是this.Delegate将变成一个你按制影片的好方法。