KnockoutJS - Observáveis ​​Computados

Computed Observable é uma função que depende de um ou mais Observables e atualiza automaticamente sempre que seus Observables subjacentes (dependências) mudam.

Os observáveis ​​computados podem ser encadeados.

Sintaxe

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

Exemplo

Vejamos o seguinte exemplo, que demonstra o uso de Observáveis ​​Computados.

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

Nas linhas a seguir, as duas primeiras são para aceitar valores de entrada. A terceira linha imprime a média desses dois números.

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

Nas linhas a seguir, tipo de Observáveis a e bé o número quando eles são inicializados pela primeira vez dentro de ViewModel. No entanto, em KO, cada entrada aceita da IU é, por padrão, no formato String. Portanto, eles precisam ser convertidos para o número para realizar uma operação aritmética neles.

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

Na linha a seguir, a média calculada é exibida na IU. Observe que o tipo de ligação de dados de totalAvg é apenas texto.

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

Resultado

Vamos realizar as seguintes etapas para ver como funciona o código acima -

  • Salve o código acima em computed-observable.htm Arquivo.

  • Abra este arquivo HTML em um navegador.

  • Insira quaisquer 2 números nas caixas de texto e observe que a média é calculada.

Gerenciando 'Isto'

Observe que no exemplo acima, o segundo parâmetro é fornecido como thispara função computada. Não é possível fazer referência a Observáveisa() e b() sem fornecer this.

Para superar isso, self variável é usada que contém a referência de this. Fazendo isso, não há necessidade de rastrearthisem todo o código. Em vez de,self pode ser usado.

O código ViewModel a seguir é reescrito para o exemplo acima usando 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;
   });
}

Observáveis ​​Puros Computados

Um Observable Computado deve ser declarado como PureObservável computado se esse Observável estiver simplesmente calculando e retornando o valor e não modificando diretamente os outros objetos ou estado. Pure Computed Observables ajuda Knockout a gerenciar a reavaliação e o uso de memória de forma eficiente.

Notificando assinantes explicitamente

Quando um Computed Observable está retornando um valor de tipo de dado primitivo (String, Boolean, Null e Number), seus assinantes são notificados se e somente se a mudança de valor real ocorrer. Isso significa que se um Observable recebeu o mesmo valor do valor anterior, então seus assinantes não são notificados.

Você pode fazer com que os Observáveis ​​Computados sempre notifiquem explicitamente os observadores, mesmo que o novo valor seja igual ao antigo, usando o notify sintaxe da seguinte forma.

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

Limitando notificações de mudança

Muitas atualizações caras podem resultar em problemas de desempenho. Você pode limitar o número de notificações a serem recebidas do Observable usandorateLimit atributo da seguinte forma.

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

Descobrir se uma propriedade é computável como observável

Em certas situações, pode ser necessário descobrir se uma propriedade é um Observável Computado. As funções a seguir podem ser usadas para identificar os tipos de observáveis.

Sr. Não. Função
1

ko.isComputed

Devoluções true se a propriedade for Computed Observable.

2

ko.isObservable

Devoluções true se a propriedade for Observable, Observable array ou Computed Observable.

3

ko.isWritableObservable

Devoluções truese observável, matriz observável ou observável computável gravável. (Isso também é chamado de ko.isWriteableObservable)

Observáveis ​​computadorizados graváveis

Computed Observable é derivado de um ou vários outros Observables, portanto, é somente leitura. No entanto, é possível tornar o Computed Observable gravável. Para isso, você precisa fornecer uma função de retorno de chamada que funcione em valores escritos.

Esses Observáveis ​​Computados graváveis ​​funcionam exatamente como os Observáveis ​​normais. Além disso, eles exigem que uma lógica personalizada seja construída para interferir nas ações de leitura e gravação.

Pode-se atribuir valores a muitas propriedades observáveis ​​ou observáveis ​​computadas usando a sintaxe de encadeamento a seguir.

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

Exemplo

O exemplo a seguir demonstra o uso de Observável Computável Gravável.

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

No código acima, rawDate é a propriedade pureComputed aceita da IU. yourAge Observável é derivado de rawDate.

As datas em JavaScript são manipuladas em milissegundos. Portanto, ambas as datas (data de hoje e data de nascimento) são convertidas em milissegundos e, em seguida, a diferença entre elas é convertida novamente em anos e meses.

Resultado

Vamos realizar as seguintes etapas para ver como funciona o código acima -

  • Salve o código acima em writable_computed_observable.htm Arquivo.

  • Abra este arquivo HTML em um navegador.

  • Insira qualquer data de nascimento e observe que a idade é calculada.