我是KnockoutJS的新手,很想知道这是否可行。我试图将本地存储对象包装在可写的计算中,以便我可以利用KnockoutJS的自动绑定优势。但是,“读取”操作不会引用任何可观察对象 - 因此初始值永远不会更新:
<select data-bind="foreach: logLevelsArray, value: currentLogLevel">
<option data-bind="attr: { value: $index() }, text: $data"></option>
</select>
_.extend(DevUtilitiesViewModel.prototype, {
...
logLevelsArray: ['error', 'warning', 'info', 'debug'],
currentLogLevel: ko.computed({
read: function() {
return localStorage.getItem("logger-level");
},
write: function( newValue ) {
localStorage.setItem("logger-level", newValue);
}
})
...
});
DevUtilitiesViewModel.currentLogLevel(); // 2 (default)
DevUtilitiesViewModel.currentLogLevel(4);
localStorage.getItem("logger-level"); // 4 - write was successful
DevUtilitiesViewModel.currentLogLevel(); // 2 - still the original value
我明白这是预期的行为,我理解为什么。我也明白我可以使currentLogLevel
成为一个简单的observable并订阅它并以这种方式更新本地存储。但是我必须跟踪订阅并手动处理它,编写更多代码,等等。我只是想看看是否有办法做我想做的事情:为本地存储提供一个可观察的getter / setter。
答案 0 :(得分:6)
您需要提出一个方案,以便对本地存储的任何更改进行通知,以便您可以依赖它们。
装饰localStorage.setItem()
函数(以及可选的localStorage.removeItem()
函数)以通知任何更改。同时收听来自其他打开标签的更改的storage
事件。
有了这个,我们需要在你的observable上注册一个依赖项。看起来唯一的方法是使用observable作为通知源并调用它。您可以将此逻辑包装在localStorageObservable
。
(function () {
var localStorageObserver = ko.observable();
function notifier(fn) {
return function () {
fn.apply(this, arguments);
localStorageObserver.notifySubscribers(arguments[0]);
};
}
localStorage.setItem = notifier(localStorage.setItem);
localStorage.removeItem = notifier(localStorage.removeItem);
window.addEventListener('storage', function (event) {
localStorageObserver.notifySubscribers(event.key);
}, false);
// not sure how to capture changes in the form:
// localStorage.property = value;
ko.localStorageObservable = function (key) {
var target = ko.dependentObservable({
read: function () {
localStorageObserver(); // register on any changes
return localStorage.getItem(key);
},
write: function (value) {
localStorage.setItem(key, value);
}
});
target.key = key;
return target;
};
}());
有了这个,您现在可以与本地存储同步。
_.extend(DevUtilitiesViewModel.prototype, {
...
logLevelsArray: ['error', 'warning', 'info', 'debug'],
currentLogLevel: ko.localStorageObservable('logger-level'),
...
});
答案 1 :(得分:0)
如果您只想检测何时使用可写计算机write
方法,则可以使用observable
轻松处理通知:
currentLogLevel: ko.computed({
owner: ko.observable(localStorage.getItem("logger-level")),
read: function() { return this() },
write: function( newValue ) {
localStorage.setItem("logger-level", newValue);
this( newValue );
}
})
请记住,虽然这不会发现localStorage