Knockoutjs-computed-observables
KnockoutJS-計算されたオブザーバブル
Computed Observableは、1つ以上のObservableに依存する関数であり、基礎となるObservable(依存関係)が変更されるたびに自動的に更新されます。
計算されたオブザーバブルは連鎖できます。
構文
this.varName = ko.computed(function(){
...
...// function code
...
},this);
例
Computed Observablesの使用を示す次の例を見てみましょう。
<!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>
次の行で、Observables a および b のタイプは、ViewModel内で初めて初期化されたときの数値です。 ただし、KOでは、UIから受け入れられるすべての入力はデフォルトで文字列形式です。 したがって、算術演算を実行するには、それらをNumberに変換する必要があります。
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 ファイルに保存します。
- このHTMLファイルをブラウザーで開きます。
- テキストボックスに2つの数値を入力し、平均が計算されることを確認します。
「これ」の管理
上記の例では、2番目のパラメーターが計算関数に this として提供されていることに注意してください。 this を指定せずにObservables * a()および b()*を参照することはできません。
これを克服するために、 this の参照を保持する self 変数が使用されます。 そうすることで、コード全体で 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;
});
}
純粋な計算された観測可能量
Computed Observableが値を計算して返すだけで、他のオブジェクトや状態を直接変更しない場合、Computed Observableは Pure Computed Observableとして宣言する必要があります。 Pure Computed Observablesは、Knockoutが再評価とメモリ使用を効率的に管理するのに役立ちます。
サブスクライバーへの明示的な通知
Computed Observableがプリミティブデータ型の値(String、Boolean、Null、およびNumber)を返している場合、実際の値が変更された場合にのみ、サブスクライバーに通知されます。 Observableが以前の値と同じ値を受け取った場合、そのサブスクライバーには通知されません。
次のように notify 構文を使用することにより、新しい値が古い値と同じであっても、計算オブザーバブルを常に明示的にオブザーバーに通知することができます。
myViewModel.property = ko.pureComputed(function() {
return ...; //code logic goes here
}).extend({ notify: 'always' });
変更通知の制限
高価な更新が多すぎると、パフォーマンスの問題が発生する可能性があります。 次のように rateLimit 属性を使用して、Observableから受信する通知の数を制限できます。
//make sure there are updates no more than once per 100-millisecond period
myViewModel.property.extend({ rateLimit: 100 });
プロパティが計算可能かどうかを調べる
特定の状況では、プロパティが計算された観測可能かどうかを調べることが必要になる場合があります。 以下の関数を使用して、Observableのタイプを識別できます。
Sr.No. | Function |
---|---|
1 |
ko.isComputed プロパティがComputed Observableの場合、 true を返します。 |
2 |
ko.isObservable プロパティがObservable、Observable array、またはComputed Observableの場合、 true を返します。 |
3 |
ko.isWritableObservable Observable、Observable array、またはWritable Computed Observableの場合、 true を返します。 (これはko.isWriteableObservableとも呼ばれます) |
書き込み可能な計算されたオブザーバブル
Computed Observableは、1つまたは複数の他のObservableから派生しているため、読み取り専用です。 ただし、Computed Observableを書き込み可能にすることは可能です。 このためには、書き込まれた値で機能するコールバック関数を提供する必要があります。
これらの書き込み可能なComputed Observableは、通常のObservableと同じように機能します。 さらに、干渉する読み取りおよび書き込みアクションのためにカスタムロジックを構築する必要があります。
次のようなチェーン構文を使用して、多くのObservablesまたはComputed Observableプロパティに値を割り当てることができます。
myViewModel.fullName('Tom Smith').age(45)
例
次の例は、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>
上記のコードでは、 rawDate はUIから受け入れられるpureComputedプロパティです。 yourAge Observableは rawDate から派生しています。
JavaScriptの日付はミリ秒単位で操作されます。 したがって、両方の日付(今日の日付と生年月日)がミリ秒に変換され、それらの差が年と月に変換されます。
出力
上記のコードがどのように機能するかを確認するために、次の手順を実行してみましょう-
- 上記のコードを writable_computed_observable ファイルに保存します。
- このHTMLファイルをブラウザーで開きます。
- 生年月日を入力し、年齢が計算されることを確認します。