2012-05-31 3 views
0

Я создаю JQuery плагин для присоединения событий и обработчиков событий во время выполнения:Использование замыкания в JQuery

HTML-:

<table id="digitalInputsTable"> 
<thead> 
    <th>Name</th> 
    <th>Value</th> 
    <th>State</th> 
    <th>Enabled</th> 
    <th>Polarity</th> 
    <th>Ignore Reset</th>  
</thead> 
<tbody> 
    <tr>  
     <td> 
      <span class="">Name1</span>  
     </td> 
     <td> 
      <span class="">0</span> 
     </td> 
     <td> 
      <span class="">Normal</span> 
     </td> 
     <td> 
      <input type="checkbox" value="true" class="" jqmon="0" jqreg="0" id="digitalInputsTable_checkbox_03"> 
     </td> 
     <td> 
      <select class="" jqmon="0" jqreg="0" id="digitalInputsTable_select_04"> 
       <option value="0=Alarm">0=Alarm</option> 
       <option value="1=Alarm">1=Alarm</option> 
      </select>  
     </td> 
     <td>   
      <input type="checkbox" value="true" class="" jqmon="0" jqreg="0" id="digitalInputsTable_checkbox_05">  
     </td> 
    </tr> 
</tbody> 

Структура данных:

$("#digitalInputsTable").bindEvents({ 
    parentControl: "digitalInputsTable", 
    controls: [ 
     { 
      id: undefined, 
      name: "checkbox", 
      idStartsWith: "digitalInputsTable_checkbox_",    
      event: "click", 
      callbackHandler: "checkboxCallback"    
     }, 
     { 
      id: undefined, 
      name: "checkbox", 
      idStartsWith: "digitalInputsTable_checkbox_", 
      event: "blur", 
      callbackHandler: "blurCallback" 
     }, 
     { 
      id: undefined, 
      name: "select", 
      idStartsWith: "digitalInputsTable_select_",     
      event: "change", 
      callbackHandler: "selectCallback"    
     } 
    ] 
}); 

Плагин:

$.fn.bindEvents = function(options) {   
for(var i = 0; i < options.controls.length; i++) {  
    var control = options.controls[i]; 
    switch(control.name) { 
     case "checkbox": 
      control.name = ":checkbox"; 
      break;   
    } 

    if(control.id) { 
     // find control by ID. 
     // Attach event to the control. 
    } 
    else if(control.idStartsWith) {   
     $("#" + options.parentControl).find(control.name + "[id^=" + control.idStartsWith + "]") 
            .bind(control.event, function(e) {           
             function(ctrl) {             
              eval(ctrl.callbackHandler + "();"); 
             };           
            }(control)); 
    } 
}; 

};

Проблема:
Когда я устанавливаю флажок, я не могу вызвать функцию обратного вызова checkboxCallback. Может быть, я неправильно использую закрытие. Пожалуйста, порекомендуйте.

+0

, пожалуйста, добавьте немного больше информации: какой эффект имеет 'control.name =": checkbox "' have? Из его взглядов вы пытаетесь что-то похожее на '$ ('*: checkbox')', который ничего не вернет, вместо этого я бы пошел '$ ('* [type = \" checkbox \ "]')' - что бы работа с элементами с аргументом «тип» присутствует (входы) – mschr

+0

На самом деле это то, что я пытаюсь сделать: $ («# parentTableID» .find («: checkbox»). bind («click», function() {. ..}); Флажок: здесь действует как псевдоселектор –

+0

ah my bad; '$ (': checkbox') эквивалентно $ ('[type = checkbox]')', но тогда - будет ли [type = checkbox] [id^= "someidstart"] работать? Я бы удостоверился, что на самом деле есть набор узлов для вызова цепочки .bind на – mschr

ответ

1

Это не полный ответ, но он должен указывать на вас в правильном направлении. В основном, когда вы переходите через options.controls и вам необходимо выполнить действия в будущем, вам необходимо использовать закрытие для их разделения.

$.fn.bindEvents = function(options) { 
    // loop through the controls 
    for (var i = 0, control; control = options.controls[i]; ++i) { 
     // close over the current item 
     (function(ctrl) { 
      // you can safely use ctrl now 

      // call the callback like so 
      ctrl.callbackHandler(); 
     }(control)); 
    } 
}; 

Btw, не используйте eval вызвать обратный вызов, просто передать ссылку на функцию:

callbackHandler: checkboxCallback 

я добавил пример того, как назвать его внутри функции $.fn.bindEvents.

+0

Спасибо Джеку за ответ. Кажется, что все работает отлично, за исключением того, что браузер не распознает ctrl.callbackHandler() как действительный метод. «callbackHandler» - это свойство, а не метод. –

+0

Потому что вы передали обработчик как строку вместо объекта. Мое предположение. –

+0

Да, Джек, это правда. Обработчик передается как строка. Но это то, что я хочу, чтобы мои помощники разработчиков javascript + jquery имели. Кажется, eval - хороший вариант. Вы видите недостаток, связанный с браузером (хотя я знаю, что это не очень хорошая практика) с использованием «eval»? –

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