Как передать элементы по значению из массива в переменную в Javascript - PullRequest
1 голос
/ 27 ноября 2009

Я пытаюсь перебрать массив "fSel.sI" и, основываясь на данных внутри, передать их как значения (не ссылки) на ряд объявлений функций. Сейчас проблема в том, что mydrag содержит ссылку, и при вызове draggable он использует данные последнего элемента массива. Следовательно, когда вызывается start: drag: stop: значения не являются уникальными. Помощь

makeDraggable : function() {
        // create new draggable
        for (var i = 0; i < fSel.sI.length; i++) {
            mydrag = fSel.sI[i];
            $("#" + mydrag).draggable({
                cancel: [''],
                distance: 5,
                containment: "#fWorkspace",
                handle: mydrag,
                start: function() { dragRegister(mydrag)},
                drag: function() { dragItems(mydrag)},
                stop: function() { dragStop(mydrag)}
            });
        }
    },

Ответы [ 2 ]

3 голосов
/ 27 ноября 2009

Вы должны заглянуть в замыкания .

Попробуйте следующий код:

makeDraggable : function() {
        // create new draggable
        for (var i = 0, l = fSel.sI.length, sI = fSel.sI; i < l; i++) {
                var mydrag = sI[i];
                (function(mydrag) {
                            $("#" + mydrag).draggable({
                                    cancel: [''],
                                    distance: 5,
                                    containment: "#fWorkspace",
                                    handle: mydrag,
                                    start: function() { dragRegister(mydrag); },
                                    drag: function() { dragItems(mydrag); },
                                    stop: function() { dragStop(mydrag); }
                            });
                })(mydrag);
         }
},

Ваша проблема связана с функциями start, drag и stop. Они не исполняются немедленно; к тому времени, когда они это сделают, mydrag будет установлено другое значение. Оборачивая самовыполняющуюся функцию вокруг блока кода, содержащего эти функции, мы создаем замыкание, где mydrag не изменяется.

Примечание: Из соображений производительности при доступе к свойствам объекта более одного раза лучше создать переменную, которая ссылается (или содержит) свойство. В вашем цикле for я создал две переменные l и sI, в которых хранятся fSel.sI.length и fSel.sI (соответственно), поэтому JavaScript не должен искать sI и length свойства каждый раз вокруг цикла.

1 голос
/ 27 ноября 2009

Это потому, что вы создаете замыкание. Попробуйте вместо этого

makeDraggable : function() {
        // create new draggable
        for (var i = 0; i < fSel.sI.length; i++) {
                mydrag = fSel.sI[i];
                $("#" + mydrag).draggable({
                        cancel: [''],
                        distance: 5,
                        containment: "#fWorkspace",
                        handle: (function(mydrag){return mydrag;}(mydrag)),
                        start: (function(mydrag){return function() { dragRegister(mydrag)};}(mydrag)),
                        drag: (function(mydrag){return function() { dragItems(mydrag)};}(mydrag)),
                        stop: (function(mydrag){return function() { dragStop(mydrag)};}(mydrag))
                });
        }
    },

Посмотрите это видео, чтобы понять всю мощь и полезность Javascript замыканий: http://vimeo.com/1967261

...