Delegates

出自OpenFace

(重定向自27.Delegates)
跳转到: 导航, 搜索

Prev                                                                            Next

                             第二十二章 委派

                             第四部分 进阶概念



  本章描述委派(Delegates)的使用,它是OpenLaszlo应用程序用于当属性值改变时彼此间通信机制的一部分。

  我们通常只需要知道在脚本语言中为对象创建委派(Delegates)。对于你用标签创建的对象,例如<view>你可以使用事件处理管理通信。当使用处理时,OpenLaszlo在运行时为你管理委派(Delegates)。Delegates仍然存在与幕后,但系统透明的管理它们。尽管如此,理解标签和基于脚本的事件语法是很有帮助的。

  本文的最后部分解释了委派(Delegates)在其他的程序语言中中的相似性。


目录

概况

  委派的目的是在程序运行时为特定的方法绑定一个事件。这样"用委派记录一个事件" ,简单的理解就是给这个方法临时绑定了该事件。事件约束在方法的范围内,这意味着,事件发生时方法被执行了,直到这个委派被注销。

  值得注意的是,即使在编译时你不了解委派(Delegates)。你依然可以使用它,在程序运行时触发委派的事件,产生的名字会作为一个参数值传递。

  在LZX中,委派(Delegates)和事件相互参照定义。委派(Delegates)是指定调用方法的对象,并且事件是存储委派的对象。

  事件发生时,它轮流调用所有的委派(Delegates)。委派(Delegates)可以被看作是实例的已命名的方法。

  尽管委派(Delegates)可以与标签产生的对象一起使用,但明确的创建的委派(Delegates)通常用于在脚本中创建的对象。

  委派(Delegates)是必要的,因为有些时候你不知道编译时具体的事件应该做什么。例如,假定有一个视图,你想创建一个方法在每次按键时调用。这时,要用标签。当有时想要的事件行为依赖于事件创建的时间。那时你就要用委派(Delegates)。


LzDelegate

  使用LzDelegate类创建和管理委派(Delegates):

  创建委派(Delegates)的语法如下:

LzDelegate(object, method, sender, event)


  第3,4个参数是可选的:

var del = new LzDelegate(object, method, sender, event); 


  与之同样的是:

var del = new LzDelegate(object, method); 
del.register(sender, event);

委派(Delegates)和标签事件的关系

  Lzdelegate类用于在脚本中创建委派。     您可以通过如下方法静态的附加一个事件处理:

   <handler name="eventName" reference="eventSender">
      ...what to do...
   </handler>


  但若在编译时不知道事件名或事件传送媒介,就需要使用动态方法实现:

    <method name="methodName">
      ...what to do...
    </method>
    <method name="createDelegate>
      this.myDel = new LzDelegate(this, "methodName", eventSender, "eventName");
    </method>


  事件处理自动的为您处理产生和记录代表的所有工作:

oninit="do something or other"; 


expands to:

 <handler name="oninit" > 
     do something or other; 
 </name> 


Which expands to:

// make up a unique method name 
var uid = $m + <unique id> 
// make a method of that name to run the onclick code 
this.$m = function () { ; }; 
// make a delegate for that method 
var del = new LzDelegate(this, $m); 
// register it to receive onkeydown events 
del.register(this, 'onkeydown'); 


  下例在使用中说明类LzDelegate。


 Example 22.1 运行时记录事件

<canvas height="100"> 
   <view id="v1" x="0">
  <text id="statusText" bgcolor="green" resize="true" text="start over"/>   
  <method name="regbutton" > 
      if( (typeof this.del) == "undefined" )  {
          this.del = new LzDelegate(this, "buttonclickedagain" ); 
      }      
      this.del.register(this, "onx" );
  </method> 
  <method name="startover">
      this.del.unregisterAll(); 
      this.reset();
  </method>
  <method name="reset"> 
      this.setAttribute("x", 50);
      statusText.setAttribute("text", "Nothing special");
  </method> 
  <method name="buttonclickedagain"> 
      this.setAttribute("x", 100);
      statusText.setText("That button was clicked two or more times");
  </method> 
 </view>
 <handler name="oninit">
   v1.startover();
   v1.regbutton();
   v1.setAttribute("x",10);
 </handler> 
</canvas>

代理和存储管理

  当销毁一个对象时,例如,释放存储view的内存。尽管如此,销毁view并没有销毁与它相关的委派(Delegates)。应该手动注销委派(Delegates)一释放它占用的存储空间。


存储管理的例子

  使用委派(Delegates),动态的为事件添加一个方法:

Example 22.2 代理和存储

<class ...>
  <method name="doit"> ... </method>
  <method name="init">
    super.init();
    this.myDel = new LzDelegate(this, 'doit', libraryName, 'onload');
  </method>
  <method name="destroy">
    this.myDel.unregisterAll();  // "destroys" delegates
    super.destroy();
  </method>
</class>


委派(Delegates)作为属性的用法

  委派(Delegates)是对象,它同样可以最为另一个对象的属性。例如:

Example 22.3 代理作为属性的用法

<class name="createdelegate">
   <attribute name="mydel" type="expression" value="$once{new LzDelegate(this, 'handler')}"
</class>


  上面的代码在实例类时创建了委派(Delegates)模型。这种声明委派(Delegates)的技术具有易读的优点,并且可以确保只创建了一个委派(Delegates)。


关于其它语言中的委派(Delegates)

  这是对您可能熟悉的编程语言的委派(Delegates)的简要的讨论。

  委派(Delegates)是方法指针。它是一种方式:当我调用它时就会调用对象o的方法m。(与函数指针相反,它并不捕获对象)在Java中,可以使用匿名内部类得到同样的效果。(java使用函数创建实例)在Lisp中,使用关闭(Lisp使用context创建函数)。【Java和Lisp只是相反的两个方面】。

基本的:


// constructor 
LzDelegate = function(o, m) { this.o = o; this.m = m; } 
LzDelegate.prototype.execute = function () { with (this) { return o[m](); } }; 
var del = new LzDelegate(object, 'method'); 
del.execute(); 


  与..相同:


// constructor 
function makeDelegate (o, m) { return function () { return o[m](); }; }; 
var del = makeDelegate(object, 'method'); 
del(); 


  这里可以看到使用函数(方法)触发捕获context的‘o’,‘m’的实例和触发捕获context的‘o’and‘m’的函数作为关闭使用是类似的。


                                     Home

Prev                                                                            Next