2014-01-15 12 views
10

У меня есть приложение, которое извлекает имена проектов из базы данных, когда DOM готов. Каждый проект добавляется к <select><option> в html <form>. После заполнения списка пользователь может выбрать название проекта, которое будет запрашивать оставшуюся информацию из базы данных, относящейся к этому проекту.Событие jQuery .change() запускается только один раз

Для этого я использую метод jQuery $.change(). К сожалению, событие запускается только один раз, когда элемент <select> создается и добавляется в DOM. Выбор другого проекта из списка не запускает событие и, следовательно, не вызывает вызов $.post().

$(function(){ 
    getProjects(); 
    var firstLoad = true; 

    $("select").change(retrieveProject); // Removed parenthesis based on answers 

    // On page load, get project names from the database and add them to a Select form element 
    function getProjects() { 
     var selectionList; 
     $.getJSON("php/getProjects.php", function (data) { 
      selectionList = "<form><select>"; 
      for (var i = 0; i < data.length; i++) { 
       selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>"; 
      } 
      selectionList += "</select></form>"; 
     }).complete(function() { 
      $('#project-selection-menu').append(selectionList).removeClass('hidden'); 
      firstLoad = false; 
     }); 
    } 

    function retrieveProject() { 
     if (firstLoad == true){ 
      alert(firstLoad); // This alert fires 
      return false; 
     } else { 
      alert(firstLoad); // This alert doesn't fire 
      $.post("php/getProjects.php", function (data) { // This should have been "php/retrieveProject.php"! 
       // Do stuff with the returned data 
      }).complete(function() { 
       console.log("Success."); 
      }); 
     } 
    } 
)}; 
+0

Я ушел из анонимная функция и 'getProjects();' call для уменьшения количества показанного кода, но это, очевидно, вызвало больше путаницы. – Roy

ответ

10

Вы не настраиваете обработчик события правильно:

$("select").change(retrieveProject); 

В вашем коде вы указали функция «retrieveProject», и возвращаемое значение этого вызова функции передавалось как обработчик «изменения» (и, конечно, не имеет эффекта). Поэтому выяснилось, что событие генерировалось при загрузке страницы.

Когда вы работаете с функцией в качестве значения, вы не используете () после ссылки функции — это сама ссылка (имя функции, в данном случае), что вы хотите. Это то, что нужно передать jQuery.

Также — и это важно — убедитесь, что ваш код выполняется либо в «готовом» или «нагрузка» обработчик, или еще, что ваш <script> приходит после в <select> элемент на странице. Если скрипт находится в заголовке документа, он будет запущен до того, как DOM будет разобран, и это не будет иметь никакого эффекта. (Другой способ борьбы с этим было бы использовать .on() делегированное форму, как это предлагается в другой ответ.)


Больше: он выглядит, как вы переписав <select> элемент, когда вы запрашиваете содержание в «getProjects» , Таким образом, вы должны обязательно использовать делегированные форму:

$(document).on("change", "select", retrieveProject); 

Кроме того, вы должны использовать локальные переменные в «getProjects»:

function getProjects() { 
    var selectionList; // keep this local to the function - implicit globals are risky 

    $.getJSON("php/getProjects.php", function (data) { 
     selectionList = "<form><select>"; 
     for (var i = 0; i < data.length; i++) { 
      selectionList += "<option name='prjTitle'>" + data[i].ProjectTitle + "</option>"; 
     } 
     selectionList += "</select></form>"; 
    }).complete(function() { 
     $('#project-selection-menu').append(selectionList).removeClass('hidden'); 
     firstLoad = false; 
    }); 
} 
+0

Я отредактировал вопрос, чтобы показать, что я действительно ожидал, что DOM будет готов. Я удалил скобки после имени моей функции, и теперь ни одно из этих предупреждений не срабатывает. – Roy

+0

@ Рой хорошо «меняет» события на '