如何创建动态按钮来调用具有不同参数的函数

时间:2012-06-10 09:02:40

标签: button dynamic wsh jscript

我正在尝试为foobar2000音乐播放器在WSH组件上构建一个jscript接口 在某些时候,我需要创建一个可变数量的按钮,每个按钮调用相同的函数,但使用不同的参数。我可以使用 for loop array 创建按钮。但是,所有按钮都只会传递最后一个按钮的参数。

以下是我用来添加按钮的代码:

for (var i=0; i<_groupsArray.length; i++) {
    _btn = _groupsArray[i];
    ƒview.addButton(_btn, _img, function () {setView(_btn)}, function () {doPlay(_btn)});
}  

在这种情况下,当我点击按钮时,_btn既被用作按钮标签又想要传递给函数的参数(它将是艺术家名称或专辑标题或类似内容)。 ƒview是一个包含按钮的自定义对象。我创建它所以我不必指定按钮的位置,ƒview会在需要时计算它们。
这是实际创建按钮的addButton方法的一部分(其余部分确实计算布局)。每个action参数都作为参数传递给正在创建的按钮,而不需要addButton方法进行任何处理。

this.addButton = function(label, img, action1, action2, action3, action4, action5) {
    ...
    new ButtonObject(label, __x, __y, __w, __h, action1, action2, action3, action4, action5);

最后,我在我的buttonObject构造函数中有这个:

function ButtonObject(label, x, y, w, h, action1, action2, action3, action4, action5) {
    ...
    this.action1 = action1;
    this.action2 = action2;
    this.action3 = action3;
    this.action4 = action4;
    this.action5 = action5;
    ...
    this.act1 = function () {
        var __doIt = function () {this.action1();};
        return __doIt;
    }

for循环期间传递的函数最终将作为action1,action2 ...属性存储在对象中。
我尝试了许多使用act1方法调用 action1 的方法,包括直接调用 this.action1();使用 this.action1.apply();试图形成一个如上所述的clausure。它会调用正确的操作,但使用创建的 last 按钮的参数,否则它将崩溃或无效。

我现在没有想法尝试。我分别成功地传递了函数和参数,但这是一个丑陋的技巧。我已经阅读了一些关于clausures的教程,以及它们如何保持局部变量的活着,但在这种情况下我仍然无法让它们为我工作。当我单击“此对象不处理此属性或方法”指向该行的按钮时,我的最后一次尝试(正如您在代码中看到的那样)将崩溃

var __doIt = function () {this.action1();};

那么如何在每个按钮中保持“活着”的参数呢?

1 个答案:

答案 0 :(得分:1)

尝试类似:

for (var i=0; i<_groupsArray.length; i++) {
    _btn = _groupsArray[i];
    ƒview.addButton(_btn, _img,
        function(b) {return function () {setView(b)};}(_btn),
        function(b) {return function () {doPlay(b)};}(_btn)
    );
}

您需要创建一个闭包来保存_btn的值,而不仅仅是绑定它。额外的包装函数就是这样做的。