2013-08-21 2 views
0

Я работаю над созданием виджета, который вызывает определенный плагин для каждого элемента DOM jQuery внутри массива.Общая проблема с закрытием JavaScript в элементах jQuery в массиве

MyApp.forms - это массив объектов. Каждый объект имеет элемент DOM, обернутый jQuery.

Я делаю следующее:

$(MyApp.forms).each(function(i){ 
    var individualForm = this; 
    /* 
    individualForm is an Object { 
     prop: 'value, 
     $el: somejQueryElement, 
     ... 
    } 
    */ 
    individualForm.$el.thePlugin({ 
     // options 
    }) 
    .on('pluginEvent', function() { 
     individualForm; // refers to the last object in MyApp.forms 
     this; // refers to the last 
     $(this); // same problem 
    }).on('pluginEvent2', function() { 
     // same problem as above here. 
    }); 
}); 

pluginEvent События и pluginEvent2 привязываться ко всем individualForm «s $el. Но когда они стреляют, я всегда получаю последний элемент.
Я чувствую, что это общая проблема с закрытием JavaScript.

Я попытался использовать цикл for и создать внутри него IIFE, но он не работает, поскольку функция выполняется при срабатывании события. И хотя оба события срабатывают по всем элементам, я получаю только обработчик, прикрепленный к последнему выполняемому элементу.

Update:

Найдено затруднительное положение. Но не знаю, почему и как это сработало. Элемент individualForm.$el является элементом input с class="some-class".

В другом месте кода другой разработчик делает $('.some-class').bind(... со старой версией jQuery. И снова с новой версией jQuery (с использованием noConflict$). На странице есть 2 jQuery. Исправлено удаление первого .bind.

+0

Я сделал простую демонстрационную версию с вашей структурой здесь http://jsfiddle.net/v9hWB/ и, похоже, работает нормально –

+0

@koala_dev, да :(. Я обновил вопрос, если это помогает. Я также использую плагин перед привязкой событий –

+2

Что-то еще должно быть неправильным. Вы уверены, что 'individualForm' является локальным для обратного вызова' each'? Вы случайно устанавливаете 'individualForm. $ el' для каждого объекта одному элементу? –

ответ

-1

Можете ли вы попробовать следующее:

$(MyApp.forms).each(function(i){ 
    var form = this; 
    (function(individualForm) { 
     individualForm.$el.on('something', function() { 
      individualForm; // refers to the last object in MyApp.forms 
      this; // refers to the last 
      $(this); // same problem 
     }).on('somethingElse', function() { 
      // same problem as above here. 
     }); 
    })(form); 
}); 

Вы должны обернуть individualForm в затворе. В противном случае область изменяется и указывает на последний элемент массива.

+1

Это совершенно не нужно. Вам нужно сделать это только в том случае, если вы создаете функции внутри цикла ('for',' while', ...), которые вы здесь не делаете –

+0

Этот симптом * «Но когда они срабатывают, я всегда получаю последний элемент . * * является именно причиной такого поведения, и решение выше. Насколько я могу видеть в коде jQuery, реализация .each включает в себя цикл. Тем не менее, Om Shankar вы можете попробовать предлагаемое решение в своем коде. – Krasimir

+0

Обычная проблема с замыканием в цикле заключается в том, что переменные цикла (например, 'i')« разделяются »всеми функциями, которые создаются в цикле. Однако это не так. Обратный вызов '.each' выполняется для каждого элемента, то есть в каждом вызове создается * локальная * переменная' form'. Эта переменная не разделяется между несколькими вызовами обратного вызова '.each'. Вот демонстрация: http://jsfiddle.net/fbyvW/. Вы правы, проблема * звучит * как типичная проблема «замыкания», но в цикле кода нет замыканий, поэтому это не может быть. –