这个答案在概念上与@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。