knockout.js如何在ko.computed写入中取消confirm()后设置所选选项
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了knockout.js如何在ko.computed写入中取消confirm()后设置所选选项相关的知识,希望对你有一定的参考价值。
我有一个带选项和默认文本的选择器元素:
self._selected = ko.observable();
self.option = ko.computed({
read:function(){
return self._selected;
},
write: function(data){
if(data){
if(confirm('are you sure?')){
self._selected(data);
}else{
//reset
}
}
}
});
<select data-bind="options: options, value:option, optionsCaption: 'choose ...'"></select>
这个问题:
- 选择“一个”
- 在确认点击取消
- 所选选项仍然是“一个”仍在焦点下
它应该是“选择......”
jsbin here,仅在镀铬上进行了测试
这里存在不对称性:
当您更改选择框的值时,DOM会立即更新并随后进行淘汰(当然,淘汰赛取决于DOM更改事件)。因此,当您的代码询问“您确定吗?”时,DOM已经具有新值。
现在,当您不将该值写入绑定到value:
的observable时,viewmodel的状态不会更改。并且当可观察到的更改时,knockout仅更新DOM。因此DOM保持在选定的值,并且viewmodel中的绑定值是不同的。
最简单的方法是将旧值保存在变量中,始终将新值写入observable,如果用户单击“否”,则只需恢复旧值。这样就破坏了不对称性,DOM和视图模型保持同步。
var AppData = function(params) {
var self = {};
var selected = ko.observable();
self.options = ko.observableArray(params.options);
self.option = ko.computed({
read: selected,
write: function(value) {
var oldValue = selected();
selected(value);
if (value !== oldValue && !confirm('are you sure?')) {
selected(oldValue);
}
}
});
return self;
};
// ----------------------------------------------------------------------
ko.applyBindings(new AppData({
options: ['one','two','three']
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: options, value: option, optionsCaption: 'Select...'"></select>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
问题是底层变量的值没有变化,因此没有事件告诉Knockout它的value
与viewmodel不同步。
使用正常的可观察量,你可以调用valueHasMutated
来表示发生了一些隐匿性变化,但计算结果似乎没有。但他们确实有notifySubscribers
。事实上,你的例子非常像this example in the docs。
这是一个有效的例子:
function vm() {
const self = {};
self.options = ko.observableArray(['one', 'two', 'three']);
self._selected = ko.observable();
self.option = ko.pureComputed({
read: self._selected,
write: function(data) {
if (data) {
if (confirm('are you sure?')) {
self._selected(data);
} else {
self.option.notifySubscribers(self._selected());
}
}
}
});
return self;
}
ko.applyBindings(vm());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: options, value:option, optionsCaption: 'choose ...'"></select>
<div data-bind="text:_selected"></div>
<div data-bind="text:option"></div>
以上是关于knockout.js如何在ko.computed写入中取消confirm()后设置所选选项的主要内容,如果未能解决你的问题,请参考以下文章
在 knout.js 中遍历 observablearray 时,如何检索 foreach 的 ko.computed 运行总和