2012-06-10 3 views
1

Я пытаюсь создать интерфейс jscript для компонента WSH для музыкального проигрывателя foobar2000.
В какой-то момент мне нужно создать переменное количество кнопок, каждый из которых будет вызывать одну и ту же функцию, но с использованием другого аргумента. Я могу создать кнопки, используя для петли и массив . Тем не менее, все кнопки передадут аргумент только только.Как создать динамические кнопки для вызова функции с разными аргументами

Вот код, я использую, чтобы добавить кнопки:

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; 
    } 

функция передается во время для цикла, наконец, будет храниться в объекте как действий1, действий2 ... собственности.
Я пробовал много разных способов позвонить action1 с помощью метода act1, включая прямой вызов this.action1(); используя this.action1.apply(); пытаясь сформировать клаузур, как вы видите выше. Либо он выберет правильное действие, но будет использовать аргумент , созданный последней кнопкой, или он сработает или не будет иметь никакого эффекта.

У меня нет идей, чтобы попробовать. У меня был некоторый частичный успех, передающий функцию и аргумент отдельно, но это уродливый трюк. Я прочитал несколько руководств по clausures и как они могут поддерживать локальные переменные, но мне все равно не удалось заставить их работать для меня в этом случае. Моя последняя попытка (как вы можете увидеть его в коде) произойдет сбой, когда я нажмите на кнопку с «этот объект не обрабатывает это свойство или метод», указывающий на линии

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

Так как же я держать аргументы «живы» внутри каждой кнопки?

+0

Это звучит как проблема [Javascript закрытия внутри циклов] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example). –

ответ

1

Try что-то вроде:

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, а не только привязка к нему. Эта дополнительная функция обертки делает именно это.

Смежные вопросы