Ich fange gerade erst mit Knockout.js an (wollte es schon immer mal ausprobieren, aber jetzt habe ich endlich eine Ausrede!) - Ich habe jedoch einige wirklich schlechte Leistungsprobleme, wenn ich einen Tisch an einen relativ kleinen Satz binde Daten (ungefähr 400 Zeilen oder so).
In meinem Modell habe ich folgenden Code:
this.projects = ko.observableArray( [] ); //Bind to empty array at startup
this.loadData = function (data) //Called when AJAX method returns
{
for(var i = 0; i < data.length; i++)
{
this.projects.push(new ResultRow(data[i])); //<-- Bottleneck!
}
};
Das Problem ist, dass die for
obige Schleife mit ungefähr 400 Zeilen ungefähr 30 Sekunden dauert. Wenn ich den Code jedoch in Folgendes ändere:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
Dann for
endet die Schleife im Handumdrehen. Mit anderen Worten, die push
Methode von Knockouts observableArray
Objekt ist unglaublich langsam.
Hier ist meine Vorlage:
<tbody data-bind="foreach: projects">
<tr>
<td data-bind="text: code"></td>
<td><a data-bind="projlink: key, text: projname"></td>
<td data-bind="text: request"></td>
<td data-bind="text: stage"></td>
<td data-bind="text: type"></td>
<td data-bind="text: launch"></td>
<td><a data-bind="mailto: ownerEmail, text: owner"></a></td>
</tr>
</tbody>
Meine Fragen:
- Ist dies der richtige Weg, um meine Daten (die von einer AJAX-Methode stammen) an eine beobachtbare Sammlung zu binden?
- Ich
push
gehe davon aus, dass jedes Mal, wenn ich es aufrufe, eine gründliche Neuberechnung durchgeführt wird, z. B. das Wiederherstellen gebundener DOM-Objekte. Gibt es eine Möglichkeit, diese Neuberechnung zu verzögern oder alle meine Artikel gleichzeitig einzuschieben?
Ich kann bei Bedarf weiteren Code hinzufügen, bin mir aber ziemlich sicher, dass dies relevant ist. Zum größten Teil habe ich nur Knockout-Tutorials von der Site verfolgt.
AKTUALISIEREN:
Gemäß den folgenden Hinweisen habe ich meinen Code aktualisiert:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
Es this.projects()
dauert jedoch immer noch ungefähr 10 Sekunden für 400 Zeilen. Ich gebe zu, ich bin mir nicht sicher, wie schnell dies ohne Knockout wäre (nur Zeilen durch das DOM hinzufügen), aber ich habe das Gefühl, es wäre viel schneller als 10 Sekunden.
UPDATE 2:
Gemäß den folgenden Ratschlägen habe ich jQuery.tmpl ausprobiert (was von KnockOut nativ unterstützt wird), und diese Template-Engine zeichnet in etwas mehr als 3 Sekunden etwa 400 Zeilen. Dies scheint der beste Ansatz zu sein, kurz vor einer Lösung, bei der beim Scrollen dynamisch mehr Daten geladen werden.
valueHasMutated
macht es. Überprüfen Sie die Antwort, wenn Sie Zeit haben.