Fondamentalement, j'ai un observableArray et les valeurs pour chaque élément ne sont pas observables. Cela signifie que lorsque je modifie une valeur d'élément, l'interface utilisateur dans une boucle foreach de l'observableArray n'est pas mise à jour en conséquence.
Cela signifie un changement massif si je dois les définir sur observable. Y a-t-il moyen de rafraîchir manuellement l'interface utilisateur ou observableArray foreach?
Oui, vous pouvez appeler la fonction valueHasMutated
pour votre tableau:
yourArray.valueHasMutated();
EDIT: Si le premier n’a pas aidé, vous pouvez effectuer un rafraîchissement «en sale»:
self.refresh = function(){
var data = self.array().slice(0);
self.array([]);
self.array(data);
};
Voici le violon en marche: http://jsfiddle.net/vyshniakov/FuEy6/2/
Lorsque vous avez un tableau observable avec des éléments non observables et que certaines propriétés de l'un des éléments du tableau changent, si vous souhaitez actualiser uniquement cet élément, vous pouvez utiliser indexOf
et splice
, comme ceci:
var changedIdx = obsArray.indexOf(changedItem);
obsArray.splice(changedIdx , 1); // removes the item from the array
obsArray.splice(changedIdx , 0, changedItem); // adds it back
Ce que cela fait, c'est de rechercher l'élément dans le tableau, de le supprimer et de le réinsérer. Lorsqu'il est réinséré, l'élément est à nouveau lié aux nouvelles valeurs.
Si vous aimez cette solution, vous pouvez étendre les fonctionnalités de tous les tableaux observables ko, comme ceci:
ko.observableArray.fn.refresh = function (item) {
var index = this['indexOf'](item);
if (index >= 0) {
this.splice(index, 1);
this.splice(index, 0, item);
}
}
Ensuite, lorsque vous modifiez un élément d'un tableau, vous devez simplement effectuer cet appel:
obsArray.refresh(changedItem);
Si votre tableau contient de nombreux éléments, vous obtiendrez une performance améliorée par rapport à la régénération dirty
par Artem Vyshniakov, qui met à jour les liaisons pour tous les éléments du tableau, et pas uniquement pour celui modifié.
Remarque: la valueHasMutated
, en plus d'être non documentée (et pour usage interne, je suppose), vérifie uniquement si le tableau a été modifié, et non pas si les éléments non observables du tableau ont été modifiés. C'est à dire. il ne détecte que si vous avez ajouté des éléments au tableau, supprimé des éléments du tableau, modifié des éléments du tableau avec de nouveaux éléments différents ou modifié l'ordre des éléments. Mais il ne vérifie pas si les éléments eux-mêmes ont changé
J'ai fini par utiliser l'approche sale par le haut mais j'ai fait en sorte que tous mes tableaux observables aient cette fonctionnalité.
ko.observableArray.fn.refresh = function () {
var data = this().slice(0);
this([]);
this(data);
};
La valeur HasMutated n'a pas fonctionné pour moi. Son genre de boiteux toute la liste doit être mise à jour. Ou dans mon cas, trouvez un moyen d'étendre le plug-in ko mapping pour remplir les tableaux observables d'objets observables.
J'ai trouvé une solution simple en remplaçant l'objet entier dans le tableau.
Dans cet exemple, le paramètre ix est l'indice, oLine est l'objet mis à jour et oVM.objProps.lines contient le tableau. La solution a fonctionné comme un champion.
/* This contortion causes the computed function to fire because
* we have replaced the entire line object.
*/
function forceRefresh(ix,oLine) {
var oVM = pme.getVM();
oLine = JSON.parse(JSON.stringify(oLine));
oVM.oObjProp.lines[ix] = oLine;
}
J'utilise Knockout avec deferUpdates et la solution de JotaBe nécessite une mise à jour.
Il semble que Knockout détecte, lors de la suppression/ajout, qu'il s'agit du même élément et ne rafraîchit donc pas le tableau.
J'ai adopté la solution suivante:
ko.observableArray.fn.refresh = function (item, index) {
if (index==null) index = this['indexOf'](item);
if (index >= 0) {
this.splice(index, 1, ko.utils.extend({}, item)) // create new item
//this.splice(index, 1);
//this.splice(index, 0, item);
}
}
et il actualise le tableau correctement! :-)
Note J'ai ajouté un deuxième argument pour rafraîchir la fonction, pour spécifier l'index quand index est donné, pour éviter l'exécution d'indexOf.