2009-10-08 13 views
11

Come possiamo rendere append attendere che il precedente append sia completo. Sto aggiungendo un'enorme quantità di dati, quindi la presente appendice dovrebbe controllare se l'append precedente è completa. Sono in grado di farlo dando tutte le append in modo indipendente con un po 'di tempo. Ma praticamente secondo il mio codice potrei avere un numero "n" di appendi quindi voglio farlo dinamicamente.Attendi fino a precedente .append() è completo

Ho provato a utilizzare per o il ciclo while ma lo script si sta corrompendo e il browser si arresta in modo anomalo perché la prossima append inizia prima che l'append precedente sia completa.


$('#printall1').click(function() { 
$('#fourElementsonly').empty(); 
var cleartable = 0; 
var maxlimit = 0; 
var presentarraycount = 0; 
$.post("/PortalUserReport/getjunkdata", null, function(response, status) { 
    var report = eval(response); 
    var totalRecordsCount = report.length; //6000 
    var totalRecordsCountfortheLoop = totalRecordsCount; 
    var arraycount = Math.ceil(totalRecordsCount/1000); 
    var reports = new Array(arraycount); // reports[6] 
    for (var i = 0; i < arraycount; i++) { 
     $('#fourElementsonly').append('<table border = "1" id = "Portal_User_elements' + i + '" style = " border-collapse:collapse; width:800px; margin:0px; padding:0px; border-color:black"> </table>'); 
    } 
    reports[presentarraycount] = ""; 
    $.each(report, function(x) { 
     if (cleartable == 0) { 
      for (var i = 0; i < arraycount; i++) { 
       $('#Portal_User_elements' + i).empty(); 
      } 
      cleartable++; 
     } 
     if (recordnumber <= totalRecordsCountfortheLoop) { 
      reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td style = \"width:50px; text-align:center \"> " + recordnumber + " </td> <td style = \"width:350px;\"> Name :" + report[x].FirstName + "</td> <td style = \"width:200px;\"> UserName :" + report[x].UserName + " </td> <td style = \"width:200px; \"> Company : " + report[x].Company + " </td> </tr>"; 
      reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td > </td> <td> Registration Date : <label class = \"datepicker\"> " + report[x].ActiveDate + " </label> <td> User CN : " + report[x].UserCN + " </td> <td> Status: " + report[x].Status + " </td> </ td> </tr>"; 
      reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td> </td> <td> User Privilege : " + report[x].Privileges + " </td> <td> </td> </tr>"; 
      maxlimit++; 
      if (maxlimit == 1000) { 
       presentarraycount++; 
       reports[presentarraycount] = ""; 
       maxlimit = 0; 
      } 
     } 
     recordnumber++; 
    }); 
    for (var i = 0; i < arraycount; i++) { 
     $(this).delay(1000, function() { 
      $('#Portal_User_elements' + i).append(reports[i]); 
     }); 
    } 
}); 

}); 
+0

I dati per l'append vengono inseriti nel documento in un colpo solo o si sta utilizzando Ajax per estrarlo pezzo per pezzo? –

+0

Si prega di mostrare il codice che si sta attualmente utilizzando. – Gumbo

+0

Sto usando l'Ajax Post e ho ottenuto tutti i dati come oggetto Json. – bluwater2001

risposta

0

La soluzione seguente sta funzionando su tutti i browser in particolare IE6. Il tempo di risposta in Firefox è di 10 secondi, ma in IE6 è di 2 minuti e 30 secondi.

$('#printall1').click(function() { 
    $('#fourElementsonly').empty(); 
    var cleartable = 0; 
    var maxlimit = 0; 
    var presentarraycount = 0; 

    $.post("/PortalUserReport/getjunkdata", null, function(response, status) { 
     var report = eval(response);// we have 6000 records in the report now 
     var totalRecordsCount = report.length; // count = 6000 
     var totalRecordsCountfortheLoop = totalRecordsCount; 
     var arraycount = Math.ceil(totalRecordsCount/1000); 
     var reports = new Array(arraycount); // reports[6] 
     for (var i = 0; i < arraycount; i++) { 
      $('#fourElementsonly').append('<table border = "1" id = "Portal_User_elements' + i + '" style = " border-collapse:collapse; width:800px; margin:0px; padding:0px; border-color:black"> </table>'); 
     } 
     reports[presentarraycount] = ""; 
     $.each(report, function(x) { 
      if (cleartable == 0) { 
       for (var i = 0; i < arraycount; i++) { 
        $('#Portal_User_elements' + i).empty(); 
       } 
       cleartable++; 
      } 

      if (recordnumber <= totalRecordsCountfortheLoop) { 
       reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td style = \"width:50px; text-align:center \"> " + recordnumber + " </td> <td style = \"width:350px;\"> Name :" + report[x].FirstName + "</td> <td style = \"width:200px;\"> UserName :" + report[x].UserName + " </td> <td style = \"width:200px; \"> Company : " + report[x].Company + " </td> </tr>"; 
       reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td > </td> <td> Registration Date : <label class = \"datepicker\"> " + report[x].ActiveDate + " </label> <td> User CN : " + report[x].UserCN + " </td> <td> Status: " + report[x].Status + " </td> </ td> </tr>"; 
       reports[presentarraycount] += "<tr style = \"height:20px; border: 1px Solid Black\"> <td> </td> <td> User Privilege : " + report[x].Privileges + " </td> <td> </td> </tr>"; 
       maxlimit++; 
       if (maxlimit == 1000) { 
        presentarraycount++; 
        reports[presentarraycount] = ""; 
        maxlimit = 0; 
       } 
      } 
      recordnumber++; 
     }); 

     for (var i = 0; i < arraycount; i++) { 
      $('#Portal_User_elements' + i).append(reports[i]); 
     } 
    }); 
}); 
+3

sembra che si aggiungano singolarmente ciascun elemento nell'array del report. Questo sarà ** LENTO ** in tutti i browser, specialmente IE6. Dai un'occhiata all'articolo pubblicato in questa risposta http://stackoverflow.com/questions/1539841/wait-untill-previous-append-is-complete-jquery/1539888#1539888. Potresti anche dare un'occhiata a documentFragments - http://ejohn.org/blog/dom-documentfragments/ –

1

Sei aggiungendo agli elementi diversi o per un singolo elemento? Se stai aggiungendo un singolo elemento, potrebbe essere più facile concatenare tutti i tuoi dati e aggiungerli come un unico blocco.

Inoltre, da dove vengono i dati? Se i dati sono statici (non Ajax), allora si dovrebbe essere in grado di chiamare

$('selector').append(data1).append(data2).append(data3); 
+0

Sto usando l'Ajax Post e ottengo tutti i dati come un oggetto Json – bluwater2001

+0

Anche se i dati sono dinamici [ajax post e json object] ..se i dati restituiti sono piccoli allora possiamo usare il metodo sopra. se i dati sono grandi, il browser si bloccherà. – bluwater2001

+0

Hai avuto problemi con il codice che hai postato? Perché, per quanto posso dire, dovrebbe funzionare ogni volta che aggiungi dati a un elemento diverso. – Rowan

15

Purtroppo, la funzione di jQuery append() non include un callback. Non c'è modo di verificare veramente il completamento di esso, come si suppone accada immediatamente.

See Here per alcune informazioni su come utilizzare append in modo efficiente. In pratica, puoi provare a recuperare tutto il testo in una variabile e utilizzare semplicemente append una volta.

[aggiornamento] Dal momento che hai tutti i tuoi dati in un oggetto JSON dall'inizio, esegui il ciclo e inserisci tutto in una variabile, quindi aggiungilo appena hai finito. [/ update]

+0

Il link al post è sottovalutato – Matthew

4

Posso darvi alcuni suggerimenti su come migliorare il vostro codice.

for (var i = 0; i < arraycount; i++) { 
     $('#fourElementsonly').append('<table border = "1" id = "Portal_User_elements' + i + '" style = " border-collapse:collapse; width:800px; margin:0px; padding:0px; border-color:black"> </table>'); 
    } 

può diventare:

var html = ''; 
    for (var i = 0; i < arraycount; i++) { 
     html += '<table border = "1" id = "Portal_User_elements' + i + '" class="portalUserElements"> </table>'; 
    } 
    $('#fourElementsonly').append(html); 

si compirà:

  • 999 meno selezioni jQuery a '#fourElementsonly'
  • meno codice da iniettare se si mette nella classe "portalUserElements" gli stili:
    border-collapse: collapse; larghezza: 800px; margine: 0px; padding: 0px; border-color: black

Questo significa che è possibile anche:

for (var i = 0; i < arraycount; i++) { 
     $('#Portal_User_elements' + i).empty(); 
    } 

diventa (senza ciclo for!):

$('.portalUserElements').empty(); 

E:

for (var i = 0; i < arraycount; i++) { 
    $('#Portal_User_elements' + i).append(reports[i]); 
} 

maggio diventano:

$('.portalUserElements').each(
    function(i) { 
     $(this).append(reports[i]); 
    } 
); 

Edit: questi cambiamenti sono suggeriti per migliorare le prestazioni algoritmo, pur mantenendo la piena funzionalità è fornisce.
È possibile compattare tutto all'interno di una variabile a stringa singola (incluse le tabelle) e aggiungerlo alla fine.
Vedi gli articoli che Russ Cam ti ha suggerito in una delle sue risposte.

4

Un modo goffo ...

Una funzione (la funzione esistente) gestisce tutte le accodamento. Il codice che ha seguito le appendici è racchiuso in una nuova funzione "kickOffTheRestOfTheProcess".

Dopo aver aggiunto tutte le appendici iniziali, aggiungi un'appendice finale. Non verrà eseguito fino a tutti gli altri.

$('body')).append("<script>kickOffTheRestOfTheProcess();</script>"); 

Ha funzionato per me.

0

Forse un altro modo sarebbe stato semplicemente controllare se la lunghezza del innerHTML del contenitore che si sta aggiungendo è uguale alla lunghezza dell'ultimo pezzo di contenuto, all'interno della funzione di polling.

Se non si aggiunge, se così si aggiunge.

1

Sulla base della risposta da animuson, ho trovato questa soluzione per essere molto elegante ...

$(".selector").append(content).append(function() { //code goes here to run }); 
+0

Queste sono le cose che mi fanno andare avanti di giorno in giorno.Come trovare un'altra ciambella nella scatola. – Sam

0

edificio sui ragazzi risposte sopra ho fatto questo in angolare:

el.append('<span>random stuff</span>').append('{{randomFunction()}}'); 
1

Molto semplice :)

Utilizzo della funzione quando.

$('<div id="appendedItem">Here</div>').appendTo("body"); 
$.when($("#appendedItem").length > 0).then(function(){ 
    console.log($("#appendedItem").length); 
});