KnockoutJS-計算されたオブザーバブル

Computed Observableは、1つ以上のObservableに依存し、基礎となるObservable(依存関係)が変更されるたびに自動的に更新される関数です。

計算されたオブザーバブルは連鎖させることができます。

構文

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

ComputedObservablesの使用法を示す次の例を見てみましょう。

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

次の行で、最初の2つは入力値を受け入れるためのものです。3行目は、これら2つの数値の平均を出力します。

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

次の行では、オブザーバブルのタイプ a そして bViewModel内で初めて初期化されたときの数値です。ただし、KOでは、UIから受け入れられるすべての入力は、デフォルトで文字列形式です。したがって、それらに対して算術演算を実行するには、それらを数値に変換する必要があります。

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

次の行では、計算された平均がUIに表示されます。totalAvgのデータバインドタイプは単なるテキストであることに注意してください。

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

出力

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します computed-observable.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • テキストボックスに任意の2つの数値を入力し、平均が計算されることを確認します。

「これ」の管理

上記の例では、2番目のパラメーターは次のように提供されていることに注意してください。 this計算関数へ。Observablesを参照することはできませんa() そして b() 提供せずに this

これを克服するために、 self の参照を保持する変数が使用されます this。そうすることで、追跡する必要はありませんthisコード全体。代わりに、self に使える。

次のViewModelコードは、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;
   });
}

純粋な計算されたオブザーバブル

ComputedObservableは次のように宣言する必要があります PureObservableが単に値を計算して返すだけで、他のオブジェクトや状態を直接変更していない場合は、ComputedObservable。Pure Computed Observablesは、Knockoutが再評価とメモリ使用量を効率的に管理するのに役立ちます。

サブスクライバーに明示的に通知する

Computed Observableがプリミティブデータ型の値(String、Boolean、Null、およびNumber)を返す場合、実際の値の変更が行われた場合にのみ、そのサブスクライバーに通知されます。これは、Observableが前の値と同じ値を受け取った場合、そのサブスクライバーに通知されないことを意味します。

新しい値が古い値と同じであっても、Computed Observablesを常に明示的にオブザーバーに通知するようにするには、 notify 構文は次のとおりです。

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

変更通知の制限

高価な更新が多すぎると、パフォーマンスの問題が発生する可能性があります。を使用して、Observableから受信する通知の数を制限できます。rateLimit 次のように属性。

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

プロパティが観察可能であるかどうかを調べる

特定の状況では、プロパティがComputedObservableであるかどうかを確認する必要がある場合があります。以下の関数を使用して、Observableのタイプを識別できます。

シニア番号 関数
1

ko.isComputed

戻り値 true プロパティがComputedObservableの場合。

2

ko.isObservable

戻り値 true プロパティがObservable、Observable array、またはComputedObservableの場合。

3

ko.isWritableObservable

戻り値 trueObservable、Observable array、またはWritable ComputedObservableの場合。(これはko.isWriteableObservableとも呼ばれます)

書き込み可能な計算されたオブザーバブル

Computed Observableは、1つまたは複数の他のObservableから派生しているため、読み取り専用です。ただし、ComputedObservableを書き込み可能にすることは可能です。このためには、書き込まれた値で機能するコールバック関数を提供する必要があります。

これらの書き込み可能なComputedObservableは、通常のObservableと同じように機能します。さらに、読み取りおよび書き込みアクションを妨害するためのカスタムロジックを構築する必要があります。

次のように連鎖構文を使用して、多くのObservablesまたはComputedObservableプロパティに値を割り当てることができます。

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

次の例は、Writable ComputableObservableの使用法を示しています。

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

上記のコードでは、 rawDate UIから受け入れられるpureComputedプロパティです。 yourAge Observableはから派生しています rawDate

JavaScriptの日付は、ミリ秒単位で操作されます。したがって、両方の日付(今日の日付と生年月日)がミリ秒に変換されてから、それらの差が年と月に変換されます。

出力

上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-

  • 上記のコードをに保存します writable_computed_observable.htm ファイル。

  • このHTMLファイルをブラウザで開きます。

  • 生年月日を入力し、年齢が計算されることを確認します。