この答えは、概念的には@joshが与えたものと同じですが、より一般的なラッパーとして提示されています。注:このバージョンは、「書き込み可能」計算用です。
Typescriptを使用しているので、最初にts.d定義を含めました。したがって、関係がない場合は、この最初の部分を無視してください。
interface KnockoutStatic
{
notifyingWritableComputed<T>(options: KnockoutComputedDefine<T>, context ?: any): KnockoutComputed<T>;
}
通知-書き込み可能-計算済み
呼び出しの結果としてオブザーバブルが更新されなかった場合でもobservable
、常にサブスクライバーに通知される書き込み可能オブジェクトのラッパーwrite
Typescriptを使用しない場合は、に置き換えfunction<T> (options: KnockoutComputedDefine<T>, context)
てfunction(options, context)
ください。
ko.notifyingWritableComputed = function<T> (options: KnockoutComputedDefine<T>, context)
{
var _notifyTrigger = ko.observable(0);
var originalRead = options.read;
var originalWrite = options.write;
options.read = () =>
{
_notifyTrigger();
return originalRead();
};
options.write = (v) =>
{
originalWrite(v);
_notifyTrigger(_notifyTrigger() + 1);
};
return ko.computed(options, context);
}
これの主な使用例は、read
関数が「アクセス」するオブザーバブルの変更をトリガーしないものを更新する場合です。
たとえば、LocalStorageを使用していくつかの値を設定していますが、再評価をトリガーするためにオブザーバブルに変更はありません。
hasUserClickedFooButton = ko.notifyingWritableComputed(
{
read: () =>
{
return LocalStorageHelper.getBoolValue('hasUserClickedFooButton');
},
write: (v) =>
{
LocalStorageHelper.setBoolValue('hasUserClickedFooButton', v);
}
});
私が変更する必要があるのはにko.computed
することだけでko.notifyingWritableComputed
あり、それからすべてがそれ自体を処理することに注意してください。
hasUserClickedFooButton(true)
次に呼び出すと、「ダミー」オブザーバブルがインクリメントされ、LocalStorageの値が更新されたときに、サブスクライバー(およびそのサブスクライバー)に新しい値を取得するように強制します。
(注:notify: 'always'
エクステンダーはここではオプションだと思うかもしれませんが、それは別のことです)。
読み取り可能であるだけの計算されたオブザーバブルのための追加のソリューションがあります:
ko.forcibleComputed = function(readFunc, context, options) {
var trigger = ko.observable().extend({notify:'always'}),
target = ko.computed(function() {
trigger();
return readFunc.call(context);
}, null, options);
target.evaluateImmediate = function() {
trigger.valueHasMutated();
};
return target;
};
myValue.evaluateImmediate();
@mbestコメントからhttps://github.com/knockout/knockout/issues/1019。