2014-06-05 2 views
0

Je suis nouveau sur JavaScript. Je crée une table dynamiquement; Je suis confronté à un problème avec l'ordre d'exécution. Je sais que le code JavaScript ne s'exécutera pas séquentiellement, mais quel sera le travail?Création d'une table html en utilisant les appels ajax javascript dans un ordre séquentiel?

Je vais d'abord expliquer ce que j'essaie de faire.

1) loadList() -> Je vais appeler cette méthode sur un clic de bouton de données de charge ici, je vais tirer la demande AJAX pour obtenir des données

2) en utilisant le résultat supérieur à la demande AJAX, je suis en train de créer la table lignes

3) quelques lignes de la table td ayant zone de liste déroulante, dont la valeur à remplir en utilisant un autre appel AJAX, en passant la valeur rowObject

Voici mon code:

var loadList = function(){ 

//ajax call 
$.ajax({ 
    url:"tworows.json", 
    type: "GET", 
    dataType : "json" 
}) 
.done(function(data, textStatus, jqXHR){ 
    generateTable(data); 
}); 
}; 


function generateTable(data){ 

$("#gridTable").empty(); 

//create table header 
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>"); 

//get table id from jquery 
var tableelement = $("#gridTable"); 

//add header row to table 
tableelement.append(headertr); 


for(var i=0; i< data.links.id.length; i++){ 
     tableelement.append(createRow(data.links.id[i])); 
}  

} 

function createRow(rowObject){ 

//used to create combo box 1 based row 1 value 
var combo1 = createCombo1(rowObject); 

//used to create combo box 2 based row 1 value 
var combo2 = createCombo2(rowObject); 


var trElement = "<tr>"+ 
     "<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>"+ 
     "<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>"+ 
     "<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>"+ 
     "<td>"+combo1+"</td>"+ 
     "<td>"+combo2+"</td>"+ 
     "<td><button>Del</button></td>" + 
     "<td><button>Add</button></td></tr>"; 

return trElement; 
} 

function createCombo1(rowObject){ 

var comboList = []; 
    //call ajax to get combo value 
    $.ajax({ 
     url:"combo1data.json", 
     type: "GET", 
     dataType : "json", 
     async : false 
    }) 
    .done(function(data, textStatus, jqXHR){ 
     comboList = data.links.id; 
    });  

    var cmb1 = "<select name='cmb1' onchange='handlecmb1Change(this)'>"; 
    for(var i=0;i < comboList.length; i++){ 
    cmb1 +="<option value='"+comboList[i].id+"'>"+comboList[i].name+"</option>"; 
    } 

    cmb1 += "</select>"; 

    return cmb1; 
} 

function createCombo2(rowObject){ 
var comboList = []; 
//call ajax to get combo value 
$.ajax({ 
    url:"combo2data.json", 
    type: "GET", 
    dataType : "json", 
    async : false 
}) 
.done(function(data, textStatus, jqXHR){ 
    comboList = data.links.id; 
}); 
var cmb2 = "<select onchange='handlecmb2Change(this)'>"; 

for(var i=0;i < comboList.length; i++){ 
    cmb2 +="<option value='"+comboList[i].id+"'>"+comboList[i].name+" </option>"; 
    } 

cmb2 += "</select>"; 
return cmb2; 
} 

Ici, la ligne est créée en premier, après que le contrôle passe aux méthodes createCombo. Pour cette raison, je ne reçois pas de zones de liste déroulante dans td.

Je souhaite créer une liste déroulante basée sur le premier résultat de l'appel AJAX; en utilisant le premier résultat, j'ai besoin d'appeler 2 autres appels AJAX et de les remplir dans la combobox td.

+0

essayer asyn: false dans ajax appel – Illaya

+0

Merci Illaya, ça a marché cela signifie que si aucun appel ajax javascript puis la ligne vont par ligne dans le bon ordre? – user3231742

+0

Oui. travaille maintenant? – Illaya

Répondre

2

Veuillez utiliser le bloc de code ci-dessous, ceci pourrait résoudre votre problème. Votre besoin nécessite l'exécution synchrone des méthodes, pour cela vous devez utiliser la structure de rappel. ci-dessous est le code:

var loadList = function(){ 

//ajax call 
$.ajax({ 
    url:"tworows.json", 
    type: "GET", 
    dataType : "json" 
}) 
.done(function(data, textStatus, jqXHR){ 
    generateTable(data); 
}); 
}; 


function generateTable(data){ 

$("#gridTable").empty(); 

//create table header 
var headertr = $("<tr><th>col1 </th><th>col 2</th><th>col 3</th><th>col 4</th><th>col 5</th><th>col 6</th><th>col 7</th></tr>"); 

//get table id from jquery 
var tableelement = $("#gridTable"); 

//add header row to table 
tableelement.append(headertr); 


for(var i=0; i< data.links.id.length; i++){ 
     tableelement.append(createRow(data.links.id[i])); 
}  

} 

function createRow(rowObject){ 

var trElement = "<tr>"; 

//used to create combo box 1 based row 1 value 
var combo1 = createCombo1(rowObject,function(response){ 
    //used to create combo box 2 based row 1 value 
    var combo2 = createCombo2(rowObject,function(result){ 
     trElement+= "<td><input type='text' name='col1name' value='"+rowObject.Number+"' onblur='handleInput(this)'/></td>"; 
     trElement+="<td><input type='text' name='col3name' value='"+rowObject.name+"'/></td>"; 
     trElement+="<td><input type='text' name='col3name' value='"+rowObject.quantity+"'/></td>"; 
     trElement+="<td>"+response+"</td>"; 
     trElement+="<td>"+result+"</td>"; 
     trElement+="<td><button>Del</button></td>"; 
     trElement+="<td><button>Add</button></td></tr>"; 
    }); 
}); 

return trElement; 
} 

function createCombo1(rowObject,callback){ 

var comboList = []; 
    //call ajax to get combo value 
    $.ajax({ 
     url:"combo1data.json", 
     type: "GET", 
     dataType : "json" 
    }) 
    .done(function(data, textStatus, jqXHR){ 
     comboList = data.links.id; 
     var cmb1 = "<select name='cmb1' onchange='handlecmb1Change(this)'>"; 
     for(var i=0;i < comboList.length; i++){ 
     cmb1 +="<option value='"+comboList.id+"'>"+comboList.val+"</option>"; 
     } 

     cmb1 += "</select>"; 
     return callback(cmb1); 
    });  
} 

function createCombo2(rowObject,callback){ 

var comboList = []; 
    //call ajax to get combo value 
    $.ajax({ 
     url:"combo2data.json", 
     type: "GET", 
     dataType : "json" 
    }) 
    .done(function(data, textStatus, jqXHR){ 
     comboList = data.links.id; 


     var cmb2 = "<select name='cmb1' onchange='handlecmb1Change(this)'>"; 
     for(var i=0;i < comboList.length; i++){ 
     cmb1 +="<option value='"+comboList.id+"'>"+comboList.val+"</option>"; 
     } 

     cmb2 += "</select>"; 
     return callback(cmb2); 
    });  

} 

grâce

+1

Merci Arpit, comme je suis nouveau à JS laissez-moi savoir quelle est la meilleure pratique? async faux ou en utilisant des rappels dans ce genre de scénario? – user3231742

+0

La meilleure pratique consiste à utiliser les rappels comme je l'ai utilisé dans l'exemple ci-dessus. La raison en est qu'en utilisant la méthodologie de rappel, l'exécution en cours du processus est en attente jusqu'à ce que le rappel le provoque à nouveau. Et dans la plupart des cas où des appels AJAX asynchrones sont nécessaires, cette terminologie donne le comportement le plus précis en ce qui concerne le fait de faire async False dans l'appel AJAX. Une autre raison de faire cela est, quand nous voulons obtenir une sortie d'un appel AJAX séquentiel, il vous donne le meilleur résultat. Si ma solution vous permet d'obtenir votre résultat, veuillez le marquer comme utile. Merci. –

+0

Arpit, votre suggestion fonctionne quand async est faux. si async est vraie, la ligne ne crée pas. même si nous utilisons le rappel nous devons faire async faux? – user3231742

0

Plusieurs problèmes doivent être résolus. D'abord, la valeur de retour d'un rappel ajax n'ira nulle part.

Cette ligne

var combo1 = createCombo1(rowObject);

établirai combo1 à undefined chaque fois. Parce que createCombo1() ne retourne rien. La fonction anonyme à l'intérieur de createCombo1() est ce qui renvoie la valeur que vous recherchez, mais dans ce cas, vous ne pouvez pas utiliser cette valeur de retour. Ce que je recommande pour createCombo1() et createCombo2() est d'enregistrer la valeur de retour à une variable globale ou peut-être même un tableau, de sorte que vous pouvez y accéder quand ils ont fini.

Ce qui m'amène au prochain problème ... comment savez-vous quand ils ont fini?

jQuery a quelque chose appelé deferred object. Ce qui vous permet d'enchaîner plusieurs rappels à une fonction. Il existe une question SO similaire qui explique comment utiliser cela en utilisant When().

Here is the question

Il y a encore beaucoup à faire sur votre fin, mais nous espérons que cela vous pointera dans la bonne direction.

+0

Merci Smeegs, j'ai supprimé quelques petites choses en postant ici, je les ai corrigées, maintenant je peux générer une table. ce que j'ai obtenu est javascript aller ligne par ligne, si l'appel ajax est là signifie l'ordre des changements exe. Si vous faites async false, le flux va séquentiellement. J'espère que j'ai bien compris? – user3231742

Questions connexes