Событие изменения выпадающего списка JavaScript / jQuery с закрытием не работает - PullRequest
2 голосов
/ 06 января 2012

В моем примере кода у меня есть 2 выпадающих списка (но в реальном коде число меняется, потому что выпадающие списки создаются динамически), и я хотел подсчитать, сколько выпадающих списков выбрано с ненулевымзначение .Я использовал закрытие, чтобы отслеживать общее количество выпадающих списков с ненулевым выбранным значением.Мне это удалось (см. http://jsfiddle.net/annelagang/scxNp/9/).

Старый / рабочий код

$("select[id*='ComboBox']").each(          
          function() {              
              $(this).change(
                  function() {
                      compute(this);
              });         
      });

    var compute = (function () {
    var total = 11; 
    var selectedDdl = [];

    $("#total").text(total);     
    return function (ctrl) {
         var id = $(ctrl).attr("id");
         var ddlMeal = document.getElementById(id);
         var found = jQuery.inArray(id, selectedDdl);

        if (ddlMeal.options[ddlMeal.selectedIndex].value != 0){
             if(found == -1){
                 total += 1; 
                 selectedDdl.push(id);        
             } 
             else{
                 total = total;
             }
         }
         else {
             total -= 1;
             var valueToRemove = id;
             selectedDdl = $.grep(selectedDdl, function(val) 
                                      { return val != valueToRemove; });
         }        

         $("#total").text(total); 
    };     
}());

Примечание: Я инициализированобщая переменная с 11, потому что, как я уже упоминал в реальном коде, у меня может быть более 2 выпадающих списков, и я просто хотел проверить, будет ли мой код работать со значениями, превышающими 2.

Когда я попытался передать закрытие внутрисобытие .change (), оно больше не работает (см. http://jsfiddle.net/annelagang/scxNp/12/) Может кто-нибудь помочь мне разобраться с этим? Я делаю этот код уже несколько дней, и он становится довольно неприятным.

Новый / нерабочий код:

$("select[id*='ComboBox']").each(          
          function() {              
              $(this).change(
                  function() {
                     (function () {
                var total = 11; 
                var selectedDdl = [];

                $("#total").text(total);     
                return function (ctrl) {
                     var id = $(ctrl).attr("id");
                     var ddlMeal = document.getElementById(id);
                     var found = jQuery.inArray(id, selectedDdl);

                     if (ddlMeal.options[ddlMeal.selectedIndex].value != 0){
                         if(found == -1){
                             total += 1; 
                             selectedDdl.push(id);        
                         } 
                         else{
                             total = total;
                         }
                     }
                     else {
                         total -= 1;
                         var valueToRemove = id;
                         selectedDdl = $.grep(selectedDdl, function(val) 
                                           { return val != valueToRemove; });
                         }        
                    $("#total").text(total); 
                };     
        }());
          });         
      });

Заранее спасибо.

PS Я также открыт для менее грязных решений.

Ответы [ 3 ]

3 голосов
/ 06 января 2012

Задача

Вы возвращаете функцию из самоисполняющейся анонимной функции, но нигде не возвращаете возвращаемое значение.

Упрощение вашего кода, это выглядит так:

/* some code here */
$(this).click(function(){
    /** The following function is executed, returns result, but the
     *  result (a function) is not assigned to anything, nor returned
     */
    (function(){
        /* some code here */
        return function(ctrl){
            /* some code here */
        };
    }());
});
/* some code here */

Решение

Как правило, ваш код очень нечитабелен, вы должны улучшить его для своего же блага (и избегать таких проблем). Приведенную выше проблему можно быстро исправить, передав параметр в функцию, которая возвращает функцию (но не вызывала ее). Решение здесь: jsfiddle.net / scxNp / 13 /

Решение: объяснение

То, что я сделал, было просто - я заметил, что вы передаете this функции из первого (рабочего) примера, но вы даже не выполняете эту функцию во втором (неправильном) примере. Упрощенное решение выглядит так:

/* some code here */
$(this).click(function(){
    /** Now the result of the following function is also executed, with
     *  parameter passed as in your working example
     */
    (function(){
        /* some code here */
        return function(ctrl){
            /* some code here */
        };
    }())(this);
});
/* some code here */

Надеюсь, это имеет смысл:)

Ps. Я также обновил свой первый фрагмент кода, чтобы изменения были легко обнаружены:)

PS.2. Это всего лишь quickfix , и, как уже упоминалось выше, многое нужно сделать, чтобы сделать ваш код читабельным. Также каждая функция работает как замыкание , поэтому не злоупотребляйте самореализующимся (function(){/* your code */})();, чтобы не назначать что-либо (это полезно, но достаточно одного раза для одного сценария). Вместо используйте существующие замыкания .

2 голосов
/ 06 января 2012

Я считаю, что это должно работать:

$("select[id*='ComboBox']").change(function() {
    $("#total").text($("select[id*='ComboBox'][value!=0]").length);
});

http://jsfiddle.net/scxNp/15/

0 голосов
/ 06 января 2012

как насчет этого?

html:

<select id="ComboBox1" class="howMany">
<option value="0">Value 0</option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
<option value="3">Value 3</option>
</select>

<select id="ComboBox2" class="howMany">
<option value="0">Value 0</option>
<option value="1">Value 1</option>
<option value="2">Value 2</option>
<option value="3">Value 3</option>
</select>

<div id="total"></div>

script:

$(".howMany").change(
function ()
{
    var nonZero = 0;
    $(".howMany").each(
        function ()
        {
            if ($(this).val() != '0')
                ++nonZero;
        }           
    );
    $("#total").text('There are '+nonZero+' options selected');       
}
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...