Ta odpowiedź jest koncepcyjnie taka sama, jak ta, którą podał @josh, ale przedstawiona jako bardziej ogólne opakowanie. Uwaga: ta wersja jest przeznaczona do obliczeń z możliwością zapisu.
Używam Typescript, więc najpierw dołączyłem definicję ts.d. Więc zignoruj tę pierwszą część, jeśli nie dotyczy ciebie.
interface KnockoutStatic
{
notifyingWritableComputed<T>(options: KnockoutComputedDefine<T>, context ?: any): KnockoutComputed<T>;
}
Powiadomienie-zapisywalne-obliczone
Opakowanie dla zapisywalnego, observable
które zawsze powoduje powiadomienie subskrybentów - nawet jeśli żadne obserwowalne nie zostały zaktualizowane w wyniku write
połączenia
Wystarczy wymienić function<T> (options: KnockoutComputedDefine<T>, context)
ze function(options, context)
jeśli nie używać maszynopis.
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);
}
Głównym przypadkiem użycia jest sytuacja, gdy aktualizujesz coś, co w przeciwnym razie nie spowodowałoby zmiany w obserwowalnym, który jest „odwiedzany” przez read
funkcję.
Na przykład używam LocalStorage do ustawiania niektórych wartości, ale nie ma żadnej zmiany w żadnej obserwowalnej, aby wywołać ponowną ocenę.
hasUserClickedFooButton = ko.notifyingWritableComputed(
{
read: () =>
{
return LocalStorageHelper.getBoolValue('hasUserClickedFooButton');
},
write: (v) =>
{
LocalStorageHelper.setBoolValue('hasUserClickedFooButton', v);
}
});
Pamiętaj, że wszystko, co potrzebne do zmiany było ko.computed
, aby ko.notifyingWritableComputed
i to wszystko dba o siebie.
Kiedy hasUserClickedFooButton(true)
wywołuję, obserwowalny `` manekin '' jest zwiększany, zmuszając wszystkich subskrybentów (i ich subskrybentów) do uzyskania nowej wartości, gdy wartość w LocalStorage jest aktualizowana.
(Uwaga: możesz pomyśleć, że notify: 'always'
przedłużacz jest tutaj opcją - ale to coś innego).
Istnieje dodatkowe rozwiązanie dla obliczonego obserwowalnego, które jest tylko do odczytu:
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();
Z @mbest komentarz https://github.com/knockout/knockout/issues/1019 .