KnockoutJS - Osservabili calcolati

L'osservabile calcolato è una funzione che dipende da uno o più osservabili e si aggiorna automaticamente ogni volta che gli osservabili (dipendenze) sottostanti cambiano.

Gli osservabili calcolati possono essere concatenati.

Sintassi

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

Esempio

Esaminiamo il seguente esempio che dimostra l'uso degli osservabili calcolati.

<!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>

Nelle righe seguenti, le prime due sono per accettare i valori di input. La terza riga stampa la media di questi due numeri.

<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>

Nelle righe seguenti, tipo di Osservabili a e bè il numero quando vengono inizializzati per la prima volta in ViewModel. Tuttavia, in KO ogni input accettato dall'interfaccia utente è per impostazione predefinita nel formato String. Quindi devono essere convertiti in Numero in modo da eseguire operazioni aritmetiche su di essi.

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);

Nella riga seguente, la media calcolata viene visualizzata nell'interfaccia utente. Nota che il tipo di associazione dati di totalAvg è solo testo.

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

Produzione

Eseguiamo i seguenti passaggi per vedere come funziona il codice sopra:

  • Salva il codice sopra in formato computed-observable.htm file.

  • Apri questo file HTML in un browser.

  • Immettere 2 numeri qualsiasi nelle caselle di testo e osservare che viene calcolata la media.

Gestire "questo"

Si noti che nell'esempio precedente, il secondo parametro è fornito come thisalla funzione calcolata. Non è possibile fare riferimento agli osservabilia() e b() senza fornire this.

Per superare questo self viene utilizzata una variabile che contiene il riferimento di this. In questo modo, non è necessario tenere tracciathisin tutto il codice. Anziché,self può essere utilizzata.

Il codice ViewModel seguente viene riscritto per l'esempio precedente utilizzando 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;
   });
}

Osservabili calcolati puri

Un osservabile calcolato dovrebbe essere dichiarato come PureOsservabile calcolato se quell'osservabile sta semplicemente calcolando e restituendo il valore e non modificando direttamente gli altri oggetti o stato. Pure Computed Observables aiuta Knockout a gestire la rivalutazione e l'utilizzo della memoria in modo efficiente.

Notifica esplicitamente agli abbonati

Quando un oggetto osservabile calcolato restituisce un valore del tipo di dati primitivo (String, Boolean, Null e Number), i suoi sottoscrittori ricevono una notifica se e solo se avviene la modifica del valore effettivo. Significa che se un osservabile ha ricevuto lo stesso valore del valore precedente, i suoi abbonati non vengono informati.

Puoi fare in modo che gli osservabili calcolati notifichino sempre esplicitamente agli osservatori, anche se il nuovo valore è lo stesso del vecchio utilizzando il notify sintassi come segue.

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

Limitazione delle notifiche di modifica

Troppi aggiornamenti costosi possono causare problemi di prestazioni. Puoi limitare il numero di notifiche da ricevere da Observable utilizzandorateLimit attributo come segue.

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

Scoprire se una proprietà è osservabile calcolata

In determinate situazioni, potrebbe essere necessario scoprire se una proprietà è un osservabile calcolato. Le seguenti funzioni possono essere utilizzate per identificare i tipi di osservabili.

Sr.No. Funzione
1

ko.isComputed

ritorna true se la proprietà è calcolata osservabile.

2

ko.isObservable

ritorna true se la proprietà è Observable, Observable array o Computed Observable.

3

ko.isWritableObservable

ritorna truese osservabile, matrice osservabile o osservabile calcolata scrivibile. (Questo è anche chiamato ko.isWriteableObservable)

Osservabili calcolati scrivibili

L'osservabile calcolato è derivato da uno o più altri osservabili, quindi è di sola lettura. Tuttavia, è possibile che sia possibile rendere scrivibile Computed Observable. Per questo è necessario fornire una funzione di callback che funzioni sui valori scritti.

Questi osservabili calcolati scrivibili funzionano esattamente come normali osservabili. Inoltre, richiedono la creazione di una logica personalizzata per le azioni di lettura e scrittura che interferiscono.

È possibile assegnare valori a molte proprietà osservabili o osservabili calcolate utilizzando la sintassi del concatenamento come segue.

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

Esempio

L'esempio seguente dimostra l'uso di 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>

Nel codice sopra, rawDate è la proprietà pureComputed accettata dall'interfaccia utente. yourAge Observable è derivato da rawDate.

Le date in JavaScript vengono manipolate in millisecondi. Quindi, entrambe le date (data odierna e data di nascita) vengono convertite in millisecondi e quindi la differenza tra loro viene riconvertita in anni e mesi.

Produzione

Eseguiamo i seguenti passaggi per vedere come funziona il codice sopra:

  • Salva il codice sopra in formato writable_computed_observable.htm file.

  • Apri questo file HTML in un browser.

  • Inserisci una data di nascita e osserva che l'età viene calcolata.