Je suis juste de commencer avec Knockout.js (toujours voulu essayer, mais maintenant que j'ai enfin une excuse!) - Cependant, je suis en cours d'exécution dans certains vraiment mauvais problèmes de performances lors de la liaison d'un tableau à un petit ensemble de données (autour de 400 lignes).
Dans mon modèle, j'ai le code suivant:
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!
}
};
Le problème est l' for
boucle ci-dessus prend environ 30 secondes ou si, avec près de 400 lignes. Cependant, si je change le code:
this.loadData = function (data)
{
var testArray = []; //<-- Plain ol' Javascript array
for(var i = 0; i < data.length; i++)
{
testArray.push(new ResultRow(data[i]));
}
};
Puis l' for
boucle se termine en un clin d'œil. En d'autres termes, l' push
méthode de knock-out de l' observableArray
objet est incroyablement lent.
Voici mon template:
<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>
Mes Questions:
- Est-ce la bonne manière de lier mes données (qui provient d'une méthode AJAX) pour une collection observable?
- J'attends
push
est en train de faire la grosse re-calc chaque fois que j'appelle, comme peut-être la reconstruction lié objets DOM. Est-il un moyen de retarder ce recalcul, ou peut-être pousser dans tous mes articles à la fois?
Je peux ajouter plus de code si nécessaire, mais je suis sûr que c'est ce qui est pertinent. Pour la plupart, j'étais juste Ko suivante tutoriels du site.
Mise à JOUR:
Par les conseils ci-dessous, j'ai mis à jour mon code:
this.loadData = function (data)
{
var mappedData = $.map(data, function (item) { return new ResultRow(item) });
this.projects(mappedData);
};
Toutefois, this.projects()
encore faut environ 10 secondes pour 400 lignes. J'admets que je ne suis pas sûr de savoir comment rapide ce serait sans knock-out (ajouter des lignes à travers les DOM), mais j'ai le sentiment qu'il serait beaucoup plus vite que 10 secondes.
Mise à JOUR 2:
Pour d'autres conseils ci-dessous, j'ai donné jQuery.tmpl un coup (ce qui est pris en charge nativement par knock-out), et ce moteur de template va dessiner autour de 400 lignes dans un peu plus de 3 secondes. Cela semble être la meilleure approche, au court d'une solution qui permettrait de charger dynamiquement en plus de données que vous faites défiler.