2

我正在尝试使用淘汰赛 js 创建一个延迟加载选择。多亏了淘汰赛,按需加载数据并让它更新 UI 变得很简单。但是,一旦加载数据,我就无法设置正确的项目。

此处为示例 jsFiddle

经过一番挖掘后,似乎敲除会覆盖该值,因为它希望将模型与选项匹配。请参阅 knockout-2.2.1.debug.js 中的“ensureDropdownSelectionIsConsistentWithModelValue”。

这对我来说是个问题,因为在它这样做的时候,没有选项,所以它用 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());
4

3 回答 3

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>

这只是查看其他选项并建立一个初始值。

示例:http: //jsfiddle.net/rniemeyer/SmSC6/

于 2013-04-17T16:07:44.040 回答
1

这是一个邪恶的老问题,但我想我会为了其他任何出现并发现这个问题的人的利益而发帖。我编写了一个插件来封装可供选择对象使用的选项及其所选索引。

这个插件还解决了上面描述的原始问题,因为您可以将一个值加载到 observable 中,然后在稍后加载选项,并且如果该值存在于加载的列表中,那么 observable 将自动连接它。

看看,希望这对这些年后来的人有帮助:)

https://github.com/ozrevulsion/KoSelectSugar

于 2015-08-04T09:22:16.540 回答
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);
    });  
};
于 2013-04-17T15:32:25.737 回答