KnockoutJS - Observables calculés

Calculé Observable est une fonction qui dépend d'un ou plusieurs Observables et se met à jour automatiquement chaque fois que ses Observables sous-jacents (dépendances) changent.

Les observables calculés peuvent être chaînés.

Syntaxe

this.varName = ko.computed(function(){
   ...
   ... //  function code
   ...
},this);

Exemple

Regardons l'exemple suivant qui démontre l'utilisation des observables calculés.

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Computed Observables</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"></script>
   </head>

   <body>
      <p>Enter first number: <input data-bind = "value: a" /></p>
      <p>Enter second number: <input data-bind = "value: b"/></p>
      <p>Average := <span data-bind="text: totalAvg"></span></p>

      <script>
         function MyViewModel() {
            this.a = ko.observable(10);
            this.b = ko.observable(40);

            this.totalAvg = ko.computed(function() {

               if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
                  this.a(Number(this.a()));   //convert string to Number
                  this.b(Number(this.b()));   //convert string to Number
               }

               total = (this.a() + this.b())/2 ;
               return total;
            },this);
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

Dans les lignes suivantes, les deux premiers sont pour accepter les valeurs d'entrée. La troisième ligne imprime la moyenne de ces deux nombres.

<p>Enter first number: <input data-bind = "value: a" /></p>
<p>Enter second number: <input data-bind = "value: b"/></p>
<p>Average := <span data-bind = "text: totalAvg"></span></p>

Dans les lignes suivantes, type d'observables a et best un nombre lorsqu'ils sont initialisés pour la première fois dans ViewModel. Cependant, dans KO, chaque entrée acceptée depuis l'interface utilisateur est par défaut au format String. Ils doivent donc être convertis en nombre afin d'effectuer une opération arithmétique sur eux.

this.totalAvg = ko.computed(function() {
   
   if(typeof(this.a()) !== "number" || typeof(this.b()) !== "number") {
      this.a(Number(this.a()));   //convert string to Number
      this.b(Number(this.b()));   //convert string to Number
   }
   
   total = (this.a() + this.b())/2 ;
   return total;
},this);

Dans la ligne suivante, la moyenne calculée est affichée dans l'interface utilisateur. Notez que le type de liaison de données de totalAvg est juste du texte.

<p>Average := <span data-bind = "text: totalAvg"></span></p>

Production

Exécutons les étapes suivantes pour voir comment fonctionne le code ci-dessus -

  • Enregistrez le code ci-dessus dans computed-observable.htm fichier.

  • Ouvrez ce fichier HTML dans un navigateur.

  • Entrez 2 nombres quelconques dans les zones de texte et observez que la moyenne est calculée.

Gérer «ceci»

Notez que dans l'exemple ci-dessus, le deuxième paramètre est fourni comme thisà la fonction calculée. Il n'est pas possible de se référer aux observablesa() et b() sans fournir this.

Pour surmonter cela, self variable est utilisée qui contient la référence de this. Ce faisant, il n'est pas nécessaire de suivrethistout au long du code. Au lieu,self peut être utilisé.

Le code ViewModel suivant est réécrit pour l'exemple ci-dessus en utilisant self.

function MyViewModel(){
   self = this;
   self.a = ko.observable(10);
   self.b = ko.observable(40);

   this.totalAvg = ko.computed(function() {
      
      if(typeof(self.a()) !== "number" || typeof(self.b()) !== "number") {
         self.a(Number(self.a()));   //convert string to Number
         self.b(Number(self.b()));   //convert string to Number
      }
      
      total = (self.a() + self.b())/2 ;
      return total;
   });
}

Observables calculés purs

Un observable calculé doit être déclaré comme PureCalculé Observable si cet Observable calcule et renvoie simplement la valeur et ne modifie pas directement les autres objets ou état. Pure Computed Observables aide Knockout à gérer efficacement la réévaluation et l'utilisation de la mémoire.

Notifier explicitement les abonnés

Lorsqu'un observable calculé renvoie une valeur de type de données primitive (String, Boolean, Null et Number), ses abonnés sont informés si et seulement si le changement de valeur réelle a lieu. Cela signifie que si un observable a reçu la même valeur que la valeur précédente, ses abonnés ne sont pas notifiés.

Vous pouvez faire en sorte que les observables calculés notifient toujours explicitement les observateurs, même si la nouvelle valeur est la même que l'ancienne en utilisant le notify syntaxe comme suit.

myViewModel.property = ko.pureComputed(function() {
   return ...;    // code logic goes here
}).extend({ notify: 'always' });

Limitation des notifications de modification

Trop de mises à jour coûteuses peuvent entraîner des problèmes de performances. Vous pouvez limiter le nombre de notifications à recevoir d'Observable en utilisantrateLimit attribut comme suit.

// make sure there are updates no more than once per 100-millisecond period
myViewModel.property.extend({ rateLimit: 100 });

Savoir si une propriété est calculée observable

Dans certaines situations, il peut être nécessaire de savoir si une propriété est une observable calculée. Les fonctions suivantes peuvent être utilisées pour identifier les types d'observables.

N ° Sr. Fonction
1

ko.isComputed

Retour true si la propriété est Observable calculée.

2

ko.isObservable

Retour true si la propriété est Observable, Observable array ou Computed Observable.

3

ko.isWritableObservable

Retour truesi Observable, Tableau observable ou Observable calculé en écriture. (Ceci est également appelé ko.isWriteableObservable)

Observables calculés inscriptibles

Calculé Observable est dérivé d'un ou plusieurs autres Observables, il est donc en lecture seule. Cependant, il est possible que l'on puisse rendre accessible en écriture Computed Observable. Pour cela, vous devez fournir une fonction de rappel qui fonctionne sur les valeurs écrites.

Ces observables calculés inscriptibles fonctionnent comme des observables ordinaires. En outre, ils nécessitent la création d'une logique personnalisée pour interférer avec les actions de lecture et d'écriture.

On peut attribuer des valeurs à de nombreuses propriétés observables ou observables calculées en utilisant la syntaxe de chaînage comme suit.

myViewModel.fullName('Tom Smith').age(45)

Exemple

L'exemple suivant montre l'utilisation de Writable Computable Observable.

<!DOCTYPE html>
   <head >
      <title>KnockoutJS Writable Computed Observable</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
   </head>

   <body>
      <p>Enter your birth Date: <input type = "date" data-bind = "value: rawDate" ></p>
      <p><span data-bind = "text: yourAge"></span></p>

      <script>
         function MyViewModel() {
            this.yourAge = ko.observable();
            today = new Date();
            rawDate = ko.observable();

            this.rawDate = ko.pureComputed ({

               read: function() {
                  return this.yourAge;
               },

               write: function(value) {
                  var b = Date.parse(value);    // convert birth date into milliseconds
                  var t = Date.parse(today);    // convert todays date into milliseconds
                  diff = t - b;                 // take difference
                  var y = Math.floor(diff/31449600000);     // difference is converted
                                                            // into years. 31449600000
                                                            //milliseconds form a year.

                  var m = Math.floor((diff % 31449600000)/604800000/4.3);  // calculating
                                                                           // months.
                                                                           // 604800000
                                                                           // milliseconds
                                                                           // form a week.

                  this.yourAge("You are " + y + " year(s) " + m +" months old.");
               },
               owner: this
            });
         }

         ko.applyBindings(new MyViewModel());
      </script>

   </body>
</html>

Dans le code ci-dessus, rawDate est la propriété pureComputed acceptée depuis l'interface utilisateur. yourAge Observable est dérivé de rawDate.

Les dates en JavaScript sont manipulées en millisecondes. Par conséquent, les deux dates (date d'aujourd'hui et date de naissance) sont converties en millisecondes, puis la différence entre elles est reconvertie en années et en mois.

Production

Exécutons les étapes suivantes pour voir comment fonctionne le code ci-dessus -

  • Enregistrez le code ci-dessus dans writable_computed_observable.htm fichier.

  • Ouvrez ce fichier HTML dans un navigateur.

  • Entrez une date de naissance et observez que l'âge est calculé.