当通过AJAX绑定选项时,是否可以将select元素的默认值传递给Knockout
Is it possible to pass to Knockout the default value of a select element when binding the options through AJAX?
我需要通过两个不同的AJAX调用来获取<select />
的当前值和可用选项(由于几个原因,我无法对它们进行排队/连锁)。
我不知道这是否重要,但读取当前值的调用在每次读取可用选项之前完成。
使用Knockout 2.0.0和Knockout Mapping 2.0.3,我将select与data-bind="options: values, value: valueComputed"
绑定,但我发现Knockout正在删除/忽略第一个AJAX调用设置的值,直到获取可用选项的调用完成,才可能设置当前值。
这是正确的吗?是否可以告诉Knockout"这是当前值,当可用选项可用时选择它"?
经过几次测试,我想出了一个拼凑的方法:我没有将一个普通的可观测值与选择的值绑定,而是使用了一个计算的可观测量,在这里我截取了值,如果新值未定义,则不会改变基本的可观测。
我在做什么坏事吗?
jsFiddle示例:http://jsfiddle.net/KeNUU/
我正在使用的JavaScript代码:
var viewModel = function () {
var self = this;
// The underlying observable where
// the selected value is stored.
self.value = ko.observable();
// The observable bound to
// the value of the drop down.
self.values = ko.mapping.fromJS([]);
// Use a computed observable to intercept the undefined
// value placed by KnockOut when binding the drop down.
self.valueComputed = ko.computed({
"read": function () {
return ko.utils.unwrapObservable(self.value);
},
"write": function (value) {
// Update the underlying observable only when
// there is a value, if it's undefined ignore it.
if (value) {
self.value(value);
}
}
});
// Simulate the AJAX request which fetches the actual value,
// this request must complete before the second one.
setTimeout(function () {
self.valueComputed("b");
}, 1000 * 1);
// Simulate the AJAX request which fetches the available values,
// this reqest must complete after the first one.
setTimeout(function () {
ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
}, 1000 * 2);
};
$(document).ready(function () {
ko.applyBindings(new viewModel());
});
我不认为你所做的会给你带来问题,但你正在绕过KO的逻辑,以确保与值绑定的是你的选项中的有效选择。此外,如果您使用optionsCaption
提供一个空白选项,那么您将无法清除您的值。在你的情况下,这可能无关紧要。
我认为一个更简单的选择是将初始值缓存在一个不可观察的值中,然后在列表返回时使用它来填充value
。如果列表先出现,那么就没有初始值,它可以正常工作。
类似于:
setTimeout(function () {
self.initialValue = "b";
self.value("b");
}, 1000 * 1);
// Simulate the AJAX request which fetches the available values,
// this reqest must complete after the first one.
setTimeout(function () {
ko.mapping.fromJS(["a", "b", "c", "d"], {}, self.values);
if (self.initialValue) {
self.value(self.initialValue);
self.initialValue = null;
}
}, 1000 * 2);
http://jsfiddle.net/rniemeyer/gB3E5/
现在,您可以提前处理这一问题,而无需每次更改下拉列表时都要计算一个可观察的截距。
- 是否可以同时为一个元素的所有事件指定阻止默认值
- Android默认浏览器:谷歌地图制作“;位置:相对;元素在页面顶部滚动
- jQuery默认情况下不隐藏元素
- 如何在更改的事件处理程序中忽略Polymer元素上默认属性的初始覆盖
- 在javascript中阻止文档执行默认操作时,在单个元素中使用默认事件
- AngularJS:如何默认显示元素,并在按下按钮时切换
- 如何在用户离开Jquery Mobile中的页面后恢复默认HTML元素
- 如何将框元素默认组合为顶部角度 JS
- 如何在元素的默认行为之后运行单击功能
- 将新元素作为指令的默认元素应用
- 反转 HTML 元素中子项的默认 z 索引
- 如何在元素上设置默认 focus()
- 在 Javascript 中,如何从父事件处理程序中防止子元素的默认
- 零剪贴板元素在位于辅助/非默认 jQuery 选项卡中时不起作用
- 应用 css 高度后获取网页上元素的默认高度)
- 如何将自定义属性添加到 HTML 环境,该属性将默认为元素的每个新实例上的空对象
- 在 asp.net 中设置表单元素默认值
- 当我按下HTML5视频元素的默认全屏按钮时,如何捕获全屏事件
- 如何将第一个元素的 .index() 的默认索引 0 更改为 1
- 无法更改默认电子菜单上的元素