2017-05-17 3 views
1

Je suis nouveau dans Knockout. Je ne peux pas comprendre un truc que l'on trouve dans les exemples. Voici mon code. J'ai créé 3 utilisateurs ... Et ci-dessous montrent ma sortie de traitement lorsque je crée un troisième utilisateur.Knockout JS - Valeurs calculées

// It's my view 
<div id="page-container"> 

<input type="text" data-bind="value: usernameInput" /> 
<button data-bind="click: addPerson">Добавить</button> 

<ul data-bind="foreach: users"> 
    <li data-bind="text: username"></li> 
</ul> 

</div> 

<script> 
// It's my UserModel 
function UserModel(username, callback){ 
    console.log('Start creating object...'); 
    var self = this; 
    self.username = ko.observable(username); 
    self.updateCallback = ko.computed(function(){ 
     console.log('updateCallback: ' + self.username()); 
     callback(self); 
     return true; 
    }); 
}; 

// It's my ViewModel 
function ViewModel(){ 
    var self = this; 
    self.users = ko.observableArray([]); 
    self.usernameInput = ko.observable(''); 

    self.addPerson = function(){ 
     var u = self.usernameInput(); 
     var um = new UserModel(u, self.update); 
     self.users.push(um); 
     console.log('Item Pushed'); 

     self.usernameInput(''); 
     console.log('Users Collection: ' + self.users()); 
    }; 

    self.update = function(item){ 
     console.log('Update: ' + item.username()); 
     ko.utils.arrayFilter(self.users(), function(it) { 
     }); 
    }; 
}; 

ko.applyBindings(new ViewModel(), document.getElementById('page-container')); 

Il est ma sortie de la console.

Start creating object... 
updateCallback: 3 
Update: 3 
updateCallback: 1 
Update: 1 
updateCallback: 2 
Update: 2 
updateCallback: 3 
Update: 3 
Item Pushed 
Users Collection: [object Object],[object Object],[object Object] 

Cette partie je suis comprendre

Start creating object... 
updateCallback: 3 
Update: 3 

Mais quand je tente d'appeler cette fonction dans la méthode de mise à jour dans le contexte updateCallback:

ko.utils.arrayFilter(self.users(), function(it) { 
}); 

ses updateCallback calculée 3 fois, pour chaque utilisateur ...

Quelqu'un peut-il expliquer "sur les doigts" pourquoi est ce qui se passe ... Merci d'avance pour votre réponse ...

f_martinez

Il est parce que votre updateCallback calculé dépend des utilisateurs entiers de observableArray. Cette dépendance peut sembler implicite mais il est créé par rappel (auto) ...

Oui cette dépendance est implicite ... Mais cette dépendance est pas encore clair pour moi ...

Quand je utiliser LOOP mise à jour interne, comme ceci: pour (var i dans self.users()) {} il est calculé updateCallback 3 fois, pour chaque utilisateur ... Mais si je supprime la boucle et créer un troisième utilisateur ... Je vais obtenir seulement cette sortie:

Start creating object... 
updateCallback: 3 
Update: 3 
Item Pushed 
Users Collection: [object Object],[object Object],[object Object] 

Je ne peux pas comprendre comment updateCallback dépend des utilisateurs entiers observableArray ... J'utilise seulement simple boucle vide et changer quoi que ce soit à l'intérieur DonT ...

Répondre

0

Il est parce que votre updateCallback calculé dépend de toute users observableArray. Cette dépendance peut sembler implicite mais il est créé par callback(self); qui, au niveau de la pile a l'expression:

ko.utils.arrayFilter(self.users(), ...)` 

Avec chaque nouvel utilisateur, vous pouvez également créer de nouveaux calculé à l'intérieur et ce calculé dépend du tableau. Avoir deux utilisateurs dans le tableau signifie que toute modification dans ce tableau déclenchera deux calculs.

Alors ... Lorsque vous ajoutez le troisième utilisateur:

  1. le constructeur crée une plus calculée qui évalue immédiatement après la création (sorties 3), et
  2. les modifications du tableau et tous les computeds créés précédemment évaluer à nouveau (sorties 1, 2, 3).

Mise à jour

Peu importe si vous changez l'observable ou observableArray dans calculé ou non. Comme vous le savez, les observables et les tableaux observables sont réellement des fonctions. Donc, si vous appelez tout observable à l'intérieur alors cet appel est suivi pour créer une dépendance.

Et c'est vraiment cool et simple concept de Knockout entier. En passant, il y a good article about dependency tracking dans les documents officiels de KO.

+0

Bonjour, f_martinez ... Lisez ci-dessus mon message, s'il vous plaît ... J'ajoute quelques questions ... –

+0

Mis à jour ma réponse. –

0

Je comprends! Essayons d'expliquer!

J'ai ajouté quelques exemples utiles! Voir ci-dessous!

Première

<div id="page-container"> 

    <input type="text" data-bind="value: usernameInput" /> 
    <button data-bind="click: addPerson">Add</button> 
    <button data-bind="click: pushObject">Dependency</button> 

    <ul data-bind="foreach: users"> 
     <li data-bind="text: username"></li> 
    </ul> 

</div> 

<script> 

    function UserModel(username, dependency){ 
     console.log('Start creating object...'); 
     var self = this; 
     self.username = ko.observable(username); 
     self.updateCallback = ko.computed(function(){ 
      console.log(username); 
      dependency(); 
      return self.username(); 
     }); 
    }; 

    function ViewModel(){ 
     var self = this; 
     self.dependency = ko.observableArray([]); 

     self.users = ko.observableArray([]); 
     self.usernameInput = ko.observable(''); 

     self.addPerson = function(){ 
      var u = self.usernameInput(); 
      var um = new UserModel(u, self.dependency); 
      self.users.push(um); 
      console.log('Item pushed'); 
      self.usernameInput(''); 
     }; 

     self.pushObject = function(){ 
      self.dependency.push({}); 
     }; 
    }; 

</script> 

Ma Sortie de la console:

Start creating object... 
1 
Item pushed 
Start creating object... 
2 
Item pushed 
Start creating object... 
3 
Item pushed 
1 
2 
3 

Deuxième:

<div id="page-container"> 

    <input type="text" data-bind="value: usernameInput" /> 
    <button data-bind="click: addPerson">Add</button> 
    <button data-bind="click: setString">Dependency</button> 

    <ul data-bind="foreach: users"> 
     <li data-bind="text: username"></li> 
    </ul> 

</div> 

<script> 

    function UserModel(username, dependency){ 
     console.log('Start creating object...'); 
     var self = this; 
     self.username = ko.observable(username); 
     self.updateCallback = ko.computed(function(){ 
      console.log(username); 
      dependency(); 

      return self.username(); 
     }); 
    }; 

    function ViewModel(){ 
     var self = this; 
     self.users = ko.observableArray([]); 
     self.usernameInput = ko.observable(''); 

     self.dependency = ko.observable(); 

     self.addPerson = function(){ 
      var u = self.usernameInput(); 
      var um = new UserModel(u, self.dependency); 
      self.users.push(um); 
      console.log('Item pushed'); 
      self.usernameInput(''); 
     }; 

     self.setString = function(){ 
      self.dependency(''); 
     }; 
    }; 

</script> 

Ma console de sortie:

Start creating object... 
1 
Item pushed 
Start creating object... 
2 
Item pushed 
Start creating object... 
3 
Item pushed 
1 
2 
3 

Je pense que les valeurs recalculées avant l'élément poussé dans la collecte des utilisateurs. Mais en fait, son article recalculé après a poussé dans la collection des utilisateurs. C'est le POINT CLÉ !!! Et 2 bons exemples pour étudier !!!

f_martinez merci!