1

我正在尝试在 foobar2000 音乐播放器的 WSH 组件上构建 jscript 界面。
在某些时候,我需要创建可变数量的按钮,每个按钮都会调用相同的函数,但使用不同的参数。我可以使用for 循环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 方法的一部分(其余部分会计算布局)。每个动作参数都作为参数传递给正在创建的按钮,而不由 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 ... 属性存储在对象中。
我尝试了许多不同的方法来调用action1方法,包括直接调用this.action1();使用this.action1.apply();如你所见,试图形成一个从句。要么它会调用正确的操作,但使用创建的最后一个按钮的参数,要么它会崩溃或无效。

我现在没有想法尝试。我分别通过函数和参数取得了一些部分成功,但这是一个丑陋的把戏。我已经阅读了许多关于从句以及它们如何使局部变量保持活动状态的教程,但在这种情况下我仍然没有设法让它们为我工作。当我单击带有“此对象不处理此属性或方法”指向该行的按钮时,我的最后一次尝试(如您在代码中看到的那样)将崩溃

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

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

4

1 回答 1

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 的值,而不仅仅是对其的绑定。额外的包装函数正是这样做的。

于 2012-06-22T19:55:56.803 回答