【问题标题】:How do you bind a variable to a function in as3as3中如何将变量绑定到函数
【发布时间】:2011-06-08 17:57:37
【问题描述】:

我有这个代码:

for each(var tool in tools){
tool.addEventListener(MouseEvent.MOUSE_DOWN, function(){
    trace(tool); //Always the last tool  
 });
}

如何将工具的值绑定到函数,以便在回调时可以访问?

【问题讨论】:

    标签: flash actionscript-3 function binding


    【解决方案1】:

    您必须在函数内使用函数才能正确绑定作用域。这是一种在 AS3 中的 hack。如果你能帮上忙,最好不要去那个兔子洞。不过,如果你必须...

    for(var tool:Tool in _tools){
      var getHandler(scope:Tool):Function{
        var t:Tool = scope;
        return function(e:MouseEvent):void{trace(t)}
      }
      tool.addEventListener(MouseEvent.CLICK, getHandler(tool));
    }
    

    编辑:当然,您需要在处理程序中使用的任何变量也应该传递给 getHandler ......因此,您不仅可以接受范围参数,还可以传递您的 id、count、当前状态,或者其他什么。

    EDIT2:但是问自己这个问题。您将如何删除该事件侦听器?这是我说要完全避免这个兔子洞的最大原因。这是可能的,但通常比使用比 lambda 函数更 OOP 的方式解决这个问题更麻烦。

    【讨论】:

    • 如果 getHandler 被定义,而不是作为“嵌套”函数,而是在我的文档类中定义,这会起作用吗?
    • @Centipedefarmer 绝对。事实上,我会说这比我上面写的方式更好。
    • 自从开始这样做以来,我遇到了很多删除问题。我一直在创建对象的完整副本并重置变量。不是一个好的或干净的解决方案,但它有效:/
    • @QuinnBaetz 您几乎只需将该 lambda 函数存储在工具对象上的变量中,或者使用字典对象将工具存储为键并将函数存储为值。 . 有很多非常糟糕的方法可以做到这一点,还有一些不太糟糕的方法。我有一个我编写的库,它以我能想到的最不坏的方式处理这类事情……重写事件调度系统。 ;) 我一直在讨论是否将其公开。不过,如果我最终没有时间将其作为一个真正活跃的项目来维护,我会感到难过。
    【解决方案2】:

    试试这个。

    for each(var tool in tools){
      tool.addEventListener(MouseEvent.MOUSE_DOWN, toolFunction )
    }
    
    function toolFunction (e:MouseEvent){
      trace(e.currentTarget)
    }
    

    再次阅读问题标题后,我意识到,您需要的是自定义事件或:

    for each(var tool in tools){
          tool.addEventListener(MouseEvent.CLICK,
                  function(e:MouseEvent){toolFunction (e, "another param")},
                  false, 0, true);
        }
    
        function toolFunction (e:MouseEvent,anotherParam:String){
          trace(e.currentTarget)
          trace(anotherParam) //output "another param"
        }
    

    【讨论】:

    • 以后需要绑定其他的东西,不只是和mouseEvent相关的东西
    • 使用 e.currentTarget 你基本上不会对 MouseEvent 本身做太多事情,但在你的情况下使用目标元素(工具/s)。这样你总能得到正确的工具元素,而不仅仅是最后一个。如果该工具是一个对象,你可以为它分配任何你喜欢的东西。
    【解决方案3】:

    尝试做:

    for each(var tool in tools){
    var t = tool;
    t.addEventListener(MouseEvent.MOUSE_DOWN, function(){
        trace(t); //Always the last tool  
    });
    }
    

    【讨论】:

      【解决方案4】:

      您不能将函数嵌套在循环中,函数调用的参数在循环的所有迭代中都将具有相同的值,并且该值将来自最后一次迭代。有一些技巧可以解决这个问题,但这不是好的编码实践,并且将来很难修改它。

      您需要做的是更多 OOP 风格。

      由于 Tool 类显然是自定义的,因此您需要对其进行修改以保存值或您将来谈论的任何引用。
      基本上,如果您需要传递与该对象相关的值,那么只需将该值作为类 Tool 的属性。

      【讨论】:

      • 不,如果你足够狡猾的话,绝对可以提前绑定“工具”的值。这完全取决于范围管理。不过,我同意以 OOP 方式执行此操作会更好。
      【解决方案5】:

      使用 as3 信号

      http://www.peterelst.com/blog/2010/01/22/as3-signals-the-best-thing-since-sliced-bread/

      它可以很好地解决您的问题。一旦我尝试了信号,我就不能回去了。比as3中的事件系统好多了

      【讨论】:

      • 你知道,我实际上并不是 Signals 的忠实粉丝。似乎总是用一个问题(繁琐的听众体操)换另一个问题(编译时类型安全性的损失和需要访问原始源代码的难以发现的 API)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2014-12-30
      • 1970-01-01
      • 1970-01-01
      • 2011-05-17
      相关资源
      最近更新 更多