我正在尝试使用knockout js创建一个延迟加载选择。由于淘汰赛,按需加载数据并让它更新UI非常简单。但是,在加载数据后,我遇到了设置正确项目的问题。
示例jsFiddle here
经过一些挖掘后,看来淘汰会覆盖该值,因为它希望将模型与选项相匹配。请参阅' ensureDropdownSelectionIsConsistentWithModelValue'在knockout-2.2.1.debug.js。
这对我来说是一个问题,因为在这一点上,它没有选项,所以它用0覆盖我的模型值。
我是一个相当新的淘汰赛所以我怀疑我正在接近这个错误......有没有人实现这一目标?还是有更好的建议方法?
我已经阅读了Ryan的博客文章Lazy Loading an Observable in KnockoutJS,但我找不到一种方法来利用他的方法来解决我的问题。
提前感谢您的任何帮助:)
步骤。
代码示例:
HTML:
<select data-bind="options: $data.choice.options, optionsText: 'text', optionsValue: 'value', value: $data.choice"></select>
JS:
var optionsProvider = (function () {
"use strict";
var self = {};
//container for options data, a sort of dictionary of option arrays.
self.options = {};
self.init = function (optionData) {
//pre-populate any provided options data here...
};
self.get = function(name) {
if (!self.options[name]) {
self.options[name] = ko.observable([]);
//ajax request for options
//populate self.options[name] with options upon return
//dummy this with below for example.
setTimeout(function() {
self.options[name]([
{ text : "option1", value : 1 },
{ text : "option2", value : 2 },
{ text : "option3", value : 3 },
]);
}, 1000); //simulate some delay
}
//return reference to observable immediately.
return self.options[name];
};
return self;
})();
var simpleModel = function() {
this.choice = ko.observable(2); //hard code selected option to simulated pre-saved selection.
this.choice.options = optionsProvider.get("SomeOptionType");
};
ko.applyBindings(new simpleModel());
答案 0 :(得分:3)
通常,我如何处理这种情况是使用当前值作为唯一项目预先填充observableArray。
对于你,你可能会在你的getter中接受一个initialValue,如:
self.get = function(name, initialValue) {
if (!self.options[name]) {
self.options[name] = ko.observableArray([{ value: initialValue }]);
//ajax request for options
//populate self.options[name] with options upon return
//dummy this with below for example.
setTimeout(function() {
self.options[name]([
{ text : "option1", value : 1 },
{ text : "option2", value : 2 },
{ text : "option3", value : 3 },
]);
}, 1000); //simulate some delay
}
//return reference to observable immediately.
return self.options[name];
};
并将其传递给:
var simpleModel = function() {
var initialValue = 2;
this.choice = ko.observable(initialValue); //hard code selected option to simulated pre-saved selection.
this.choice.options = optionsProvider.get("SomeOptionType", initialValue);
};
以下是一个示例:http://jsfiddle.net/rniemeyer/sHB9p/
对于稍微更通用的方式,我使用了自定义绑定来实现类似:
ko.bindingHandlers.populateInitialValue = {
init: function(element, valueAccessor, allBindingsAccessor) {
var bindings = allBindingsAccessor(),
options = ko.utils.unwrapObservable(bindings.options),
optionsValue = bindings.optionsValue,
value = ko.utils.unwrapObservable(bindings.value),
initialValue;
if (options && !options.length) {
if (optionsValue) {
initialValue = {};
initialValue[optionsValue] = value;
}
else {
initialValue = value;
}
bindings.options.push(initialValue);
}
}
};
然后,使用它(不对代码进行其他更改):
<select data-bind="populateInitialValue: true, options: $data.choice.options, optionsText: 'text', optionsValue: 'value', value: $data.choice"></select>
这只是查看其他选项并构建初始值。
答案 1 :(得分:1)
这是一个邪恶的老问题,但我想我会张贴为其他任何人的利益并发现这一点。我编写了一个插件来封装选择对象可用的选项及其选定的索引。
此插件还解决了上述原始问题,因为您可以将值加载到observable中,然后在以后加载选项,如果该值存在于加载的列表中,则observable会自动将其挂起
看看,希望这可以帮助所有这些年来的所有人:)
答案 2 :(得分:0)
这是一个更新的小提琴http://jsfiddle.net/sujesharukil/5YFry/5/
您可以订阅对选项的更改,然后设置值,这是一种简单的方法。
var simpleModel = function() {
var self = this;
this.choice = ko.observable(2); //hard code selected option to simulated pre-saved selection.
this.choice.options = optionsProvider.get("SomeOptionType");
this.choice.options.subscribe(function(newValue){
self.choice(2);
});
};