2014-01-15 14 views
10

Ich habe eine Anwendung, die Projektnamen aus einer Datenbank abruft, wenn das DOM bereit ist. Jedes Projekt wird zu einem <select><option> in einem html <form> hinzugefügt. Sobald die Liste ausgefüllt ist, kann der Benutzer einen Projekttitel auswählen, der die restlichen Informationen aus der für das Projekt spezifischen Datenbank anfordert.jQuery .change() Ereignis wird nur einmal ausgelöst

Um dies zu erreichen, verwende ich die $.change() jQuery-Methode. Leider wird das Ereignis nur einmal ausgelöst, wenn das Element <select> erstellt und dem DOM hinzugefügt wird. Wenn Sie ein anderes Projekt aus der Liste auswählen, wird das Ereignis nicht ausgelöst und löst daher keinen $.post()-Aufruf aus.

$(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

verließ ich aus der anonyme Funktion und "getProjects();" Aufruf, um die Menge an Code zu reduzieren, aber es verursacht offensichtlich mehr Verwirrung. – Roy

Antwort

10

Sie sind nicht der Einrichtung der Event-Handler richtig neben handhaben:

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

In Ihrem Code waren Sie Aufruf die Funktion "retrieveProject", und der Rückgabewert dieses Funktionsaufrufs wurde als "change" -Handler übergeben (und natürlich ohne Wirkung). Aus diesem Grund schien es, dass das Ereignis beim Laden der Seite generiert wurde.

Wenn Sie mit einer Funktion als Wert arbeiten, Sie verwenden nicht () nach der Funktionsreferenz — es ist die Referenz selbst (der Name der Funktion, in diesem Fall), die Sie wollen. Das muss an jQuery übergeben werden.

Auch — und das ist wichtig — sicherstellen, dass Ihr Code ausgeführt wird entweder in einem „ready“ oder „load“ Handler, oder aber, dass Ihre <script> kommt nach das <select> Elemente auf der Seite. Wenn sich das Skript im Dokumentkopf befindet, wird es vor der Analyse des DOM ausgeführt, und es hat keine Auswirkungen. (Ein andere Möglichkeit, das zu lösen wäre eine .on() delegierte Form zu verwenden, wie in einer anderen Antwort vorgeschlagen.)


Mehr: es sieht aus wie ich ist Ihr <select> Element zu überschreiben, wenn Sie den Inhalt in „getProjects“ holen . Daher sollten Sie auf jeden Fall die delegierte Formular:

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

Außerdem sollten Sie lokale Variablen in „getProjects“ werden:

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

Ich habe die Frage bearbeitet, um zu zeigen, dass ich tatsächlich darauf gewartet habe, dass das DOM bereit ist. Ich habe die Klammer nach meinem Funktionsnamen entfernt, und jetzt werden keine der Warnungen ausgelöst. – Roy

+0

@Roy gut "ändern" Ereignisse auf '