Rya*_*ale 4 knockout.js computed-observable
我是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
Run Code Online (Sandbox Code Playgroud)
我知道这是预期的行为,我理解为什么.我也明白我可以创建currentLogLevel一个简单的observable并订阅它并以这种方式更新本地存储.但是我必须跟踪订阅并手动处理它,编写更多代码,等等.我只是想看看是否有办法做我想做的事情:为本地存储提供一个可观察的getter/setter.
您需要提出一个方案,以便对本地存储的任何更改进行通知,以便您可以依赖它们.
装饰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;
};
}());
Run Code Online (Sandbox Code Playgroud)
有了这个,您现在可以与本地存储同步.
_.extend(DevUtilitiesViewModel.prototype, {
...
logLevelsArray: ['error', 'warning', 'info', 'debug'],
currentLogLevel: ko.localStorageObservable('logger-level'),
...
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
999 次 |
| 最近记录: |