この回答は、概念的には @josh が提供したものと同じですが、より一般的なラッパーとして提示されています。注: このバージョンは「書き込み可能な」計算用です。
私は Typescript を使用しているので、最初に ts.d 定義を含めました。したがって、あなたに関係ない場合は、この最初の部分を無視してください。
interface KnockoutStatic
{
notifyingWritableComputed<T>(options: KnockoutComputedDefine<T>, context ?: any): KnockoutComputed<T>;
}
Notifying-writeable-computed
呼び出しの結果としてオブザーバブルが更新されなかった場合でも、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;
// intercept 'read' function provided in options
options.read = () =>
{
// read the dummy observable, which if updated will
// force subscribers to receive the new value
_notifyTrigger();
return originalRead();
};
// intercept 'write' function
options.write = (v) =>
{
// run logic provided by user
originalWrite(v);
// force reevaluation of the notifyingWritableComputed
// after we have called the original write logic
_notifyTrigger(_notifyTrigger() + 1);
};
// just create computed as normal with all the standard parameters
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'
(注:ここではエクステンダーはオプションだと思うかもしれませんが、それは別のことです)。
readble のみの計算されたオブザーバブルに対する追加の解決策があります。
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 .