Eventmanager调用其他对象的函数

时间:2011-11-16 13:28:15

标签: javascript jquery

我正在使用javascript和jQuery。我有一个“问题”,我的网络应用程序有不同的视图,一个动作(如鼠标点击)应该在不同的视图中做不同的事情。

我创建了一个ActionManager,在触发click事件时会收到通知。此管理器对象了解当前视图。现在我不是动作管理员能够在不同的对象中触发一个功能。

我所做的是经理获得不同对象的实例。这是通过在初始化时进行注册来完成的,在那里他们注册了他们不想处理什么样的事件以及他们负责什么样的观点。

问题是我想让它尽可能通用,这样actionmanager就不需要知道要调用的函数的名称是什么。然后,不同的实例可以具有不同的函数名称,而不让动作管理器知道它。我可以让注册部分通过发送对该函数的引用来存储该实例中该事件的函数名称,但是我不能这样做:

myfunc : function (myinstance, myfunction)
{
    myinstance.myfunction();
}

假设myfunction()作为myinstance中的函数存在,而不是使用可能是“onMouseClick”的真实函数名。

编辑: 解释其他人看到这一点并想知道原因:我的eventmanager的原因是我只想在需要它的元素上添加一个click事件,而不是更改click事件代码。我还想只调用一个方法并在该方法中运行代码。我不想调用多个方法,让方法根据视图决定它们是否应该运行。

2 个答案:

答案 0 :(得分:0)

如果myfunction是字符串:

你可以这样做:

myfunc : function (myinstance, myfunction)
{
    myinstance[myfunction]();
}

对象上的函数只是分配给该对象上的属性的函数对象。在JavaScript中,您可以通过以下两种方式之一访问属性:

  1. 使用虚线表示法和属性名称的文字,例如x = obj.foo;
  2. 使用括号表示法和字符串作为属性名称,例如x = obj["foo"];
  3. 他们做同样的事情,但当然第二种形式更加灵活 - 事实上,设计的目的正是为了描述你所处的情况。

    如果myfunction是实际的函数对象:

    你可以这样做:

    myfunc : function (myinstance, myfunction)
    {
        myfunction.call(myinstance);
    }
    

    调用myfunction并在通话过程中确保this = myinstance。所有JavaScript函数对象都具有call函数和apply函数。它们都执行相同的操作(使用特定的this值调用函数),但它们在将参数传递给函数方面有所不同:

    使用call,您可以在call调用中将它们作为离散参数传递:

    func.call(inst, arg1, arg2, arg3);
    

    使用apply,传入一组参数:

    func.apply(inst, [arg1, arg2, arg3]);
    //               ^----------------^---- note that this is an array
    

    E.g:

    var a = [arg1, arg2, arg3];
    func.apply(inst, a);
    

    以上所有

    的示例

    Live copy - 由于你说你使用的是jQuery,我继续使用它以方便使用,但上面没有一个与jQuery有关,这就是vanilla JavaScript的工作方式。

    var myinstance = {
      foo: "bar",
      myfunction: function(arg1, arg2) {
        display("<code>myfunction</code> called, <code>this.foo</code> is: " + this.foo);
        if (arg1) {
          display("<code>arg1</code> is: " + arg1);
        }
        if (arg2) {
          display("<code>arg1</code> is: " + arg2);
        }
      }
    };
    
    // Without arguments
    callUsingString(myinstance, "myfunction");
    sep();
    callUsingFunction(myinstance, myinstance.myfunction);
    sep();
    
    // With arguments
    callUsingStringWithArgs(myinstance, "myfunction", ["one", "two"]);
    sep();
    callUsingFunctionWithArgs(myinstance, myinstance.myfunction, ["one", "two"]);
    sep();
    
    function callUsingString(inst, func) {
      inst[func]();
    }
    
    function callUsingFunction(inst, func) {
      func.call(inst);
    }
    
    function callUsingStringWithArgs(inst, func, args) {
      // Easier using the function reference:
      callUsingFunctionWithArgs(inst, inst[func], args);
    }
    
    function callUsingFunctionWithArgs(inst, func, args) {
      func.apply(inst, args);
    }
    

    display只是将一个段落元素附加到包含给定文字的页面; sep只需添加hr元素。)

    更多阅读:

答案 1 :(得分:0)

如果myFunction是一个字符串,你可以这样做。

myfunc : function (myinstance, myfunction)
{
    myinstance[myfunction]();
}

但是如果myFunnction是一个函数对象,你必须调用该函数。 myFunction中的this对象引用myinstance

myfunc : function (myinstance, myfunction)
{
    myfunction.call(myinstance);
}

您可以这样做,但为什么不使用.bind()和.trigger()来处理事件? DEMO http://jsfiddle.net/DnjRs/