2016-08-05 8 views
1

Ich versuche, eine Warte gif anzuzeigen, während meine Daten geladen werden. Ich rufe einfach $(element).show() kurz vor dem Eingeben meiner $(element).each() Schleife, die alle untergeordneten Gitter anzeigt (dh. DisplayInnerTable()) mit Datenträgern.Warte GIF wird nicht angezeigt, bevor JQuery aufgerufen wird.

Es scheint, ich habe das Problem auf die .each() Methode eingegrenzt. Wenn ich den ganzen Code innerhalb der .each() entferne, wird das Wartegif immer noch nicht angezeigt, und ja, ich entferne auch die . Wenn ich kurz vor der .each() einen Haltepunkt einstelle, wird das Warte-GIF angezeigt. Scheint ein Timing-Problem zu sein, wie die .each() passiert so schnell die wait.gif innerhalb der div hat keine Zeit zu rendern. Und warum sollte Javascript Thread die Manipulation von HTML-Elementen verhindern?

Ich habe einige ähnliche Artikel gefunden, aber keiner von ihnen beantwortet dieses spezielle Problem. Die meisten anderen Artikel empfehlen die Verwendung setTimeout(). Nun, ich habe das auf jede mögliche Weise versucht, kein Glück. Jede Hilfe, Hinweise oder Hinweise werden sehr geschätzt.

Hier ist mein Code-Schnipsel:

$(document).ready(function() 
    { 
    $('#expand-all').on('click', function() { 
     $("#loader-wait-ani").show(); 
     ExpandAllChildGrids(); 
    }); 

    function ExpandAllChildGrids() 
    { 
     var tr; 
     $('#result-table tbody tr').each(function (value, index) { 
      tr = $(this).closest('tr'); 
      var row = outerTable.row(tr); 
      userId = row.cell(tr, 1).data(); 

     DisplayInnerTable(userId, row, tr); 
     }); 
     $('#expand-all-img').attr('src', '/Images/minus.gif'); 
     $("#loader-wait-ani").hide(); 
    } 
}); 

Hier ist mein html:

<div style="width:100%; margin: 0 auto; text-align:center;"> 
     <div id="loader-wait-ani" class="modal" style="display: none; z-index: 300;"> 
      <img src="~/Images/waitbar.gif" alt="Pleae Wait..." width="250" height="20" /> 
     </div> 
    </div> 
+0

Haben Sie mehrere id haben = "loader-WAIT ani "? – RIanGillis

+0

Haben Sie versucht, eine Callback-Funktion für '.show()' zu verwenden? –

+0

Sie zeigen das Lade-GIF in derselben Code-Ausführungsroutine an und blenden es aus. Dazwischen findet kein Rendering statt. Deshalb wird es nicht angezeigt. Was macht die 'DisplayInnerTable' Funktion intern? Gibt es Async-Code innerhalb der 'DisplayInnerTable', der die Zellen auffüllt? –

Antwort

1

bereits. Es ist ein Rückruf bei show() und ein Rückruf auf DisplayInnerTable()

$(document).ready(function() 
    { 
    $('#expand-all').on('click', function() { 
     $("#loader-wait-ani").show("fast", function(){ 
      ExpandAllChildGrids(); 
     }); 
    }); 

    function ExpandAllChildGrids() 
    { 
     var tr; 
     callDisplayInner(hideLoader); 
     $('#expand-all-img').attr('src', '/Images/minus.gif'); 

    } 
}); 

function hideLoader(){ 
     $("#loader-wait-ani").hide(); 
} 

function callDisplayInner(hideLoader){ 
     $('#result-table tbody tr').each(function (value, index) { 
      tr = $(this).closest('tr'); 
      var row = outerTable.row(tr); 
      userId = row.cell(tr, 1).data(); 

     DisplayInnerTable(userId, row, tr); 
     }); 
     hideLoader(); 
} 
+0

Das würde das Lade-GIF verstecken, sobald die erste Anfrage beendet ist. Das ist also nicht die beste Lösung, wenn eine Anfrage viel länger dauert als die anderen. –

+0

@ t.niese Ja, ich hatte es auf die falsche Funktion. aktualisiert auf was ich denke, wird funktionieren? –

+1

Dies funktioniert möglicherweise, wenn die Anforderungen nicht asynchron sind, aber Sie sollten davon ausgehen, dass das Browserfenster vollständig einfriert und alles, einschließlich der GIF-Animation, stoppt. Wenn die Anforderungszeit einen Ladeindikator erfordert, ist eine Synchronisierungsanforderung eine wirklich schlechte Idee. Außerdem ist async: false seit jQuery 1.8 veraltet und sollte nicht mehr verwendet werden. –

1

async: false in jeder Schleife werden Sie den Browser blockieren, bis die reponses für alle Anfragen gesendet wurden. Der Browser würde kein Rendering durchführen, bis der Code das Ende des Rückrufs erreicht hat.

Alsdann müssten Sie die Daten async anfordern und nachdem alle Daten geladen sind, müssen Sie Ihr Laden gif verstecken. Ich nehme an, dass Sie die Ajax-Methode von jQuery verwenden, damit Sie den zurückgegebenen Defere-Befehl verwenden können, um Ihre Anfragen zu verfolgen.

Manche Dinge wie folgt aus:

function DisplayInnerTable(userId, row, tr, callback) { 
    //return the Defered object of the jQuery request 
    return $.ajax('/request/to/url'); 
} 


$(document).ready(function() { 
    $('#expand-all').on('click', function() { 
    $("#loader-wait-ani").show(); 
    ExpandAllChildGrids(); 
    }); 


    function ExpandAllChildGrids() { 
    var tr; 
    var allRequests = []; 
    $('#result-table tbody tr').each(function(value, index) { 
     tr = $(this).closest('tr'); 
     var row = outerTable.row(tr); 
     userId = row.cell(tr, 1).data(); 

     //collect all Deferes in an array 
     allRequests.push(DisplayInnerTable(userId, row, tr)); 
    }); 


    $.when.apply($, allRequests) 
     .then(function() { 
     // will be executed when all requests are finished 
     $('#expand-all-img').attr('src', '/Images/minus.gif'); 
     $("#loader-wait-ani").hide(); 
     }) 
    } 
}); 

Hier einige relevante Informationen:

+0

Ihre Lösung scheint sicherlich der richtige Weg zu sein, aber leider Datatables so zu verwenden, wie ich es entworfen habe, werden die Grids nicht gerendert, wenn ich async habe: true - sonst funktioniert Ihre Lösung. Ich setze async: wahr und sicher genug das Wartegif angezeigt, aber auch wie erwartet werden die Gitter nicht rendern. – Robert