KnockoutJS选项与重复值绑定

时间:2012-02-06 14:24:04

标签: javascript knockout.js

我正在使用Knockout.js构建一个简单的应用程序作为概念证明。由于我对Knockout很新,这个问题中的代码可能远非完美并且表现出不好的做法,所以如果是这样的话,请随时告诉我!

我正在使用options绑定来生成select元素的内容:

<select data-bind="options: titles, optionsText: 'display', optionsValue: 'value'">
</select>

View Model看起来像这样:

var ViewModel = function() {
    this.titles = ko.observableArray([]);
};

在DOM准备就绪时,我将一些值推入该可观察数组(每个值都是一个对象文字,代表一个“标题”,例如“Mr”,“Mrs”等):

var data = [
    { value: "Mr", display: "Default Value" },
    { value: "Miss", display: "Miss" },
    { value: "Mr", display: "Mr" },
    { value: "Ms", display: "Ms" }
];
ko.applyBindings(view);
for(var i = 0; i < data.length; i++) {
    view.titles.push(data[i]); //Push titles into observable array
}

不要问为什么有两个具有值“Mr”的对象,这就是我必须处理的数据的方式。我无法改变它。但是,这就是导致问题的原因。我希望第一个对象代表所选的选项,但事实并非如此。第三个对象表示实际最终作为默认选择的option元素。

我相信这是因为当循环迭代时,可观察数组导致option元素逐个添加到DOM中。 Knockout尝试通过检查其值来保留所选选项。在第一次迭代之后,所选的option具有值“Mr”。在第三次迭代之后,还有另一个option,其值为“Mr”,因此Knockout认为它是之前选择的选项并选择它。

这是展示问题的link to a fiddle。应选择“默认值”选项,但不是。如果单击该按钮以再次添加具有相同值的另一个选项,则该选项将被选中,但根据文档,它不应该被选中。

我的问题是,如何防止这种行为?

1 个答案:

答案 0 :(得分:3)

为什么要逐个将项目推入数组?你可以这么做:

view.titles(data);

而不是

for(var i = 0; i < data.length; i++) {
    view.titles.push(data[i]); //Push titles into observable array
}

这也可以解决您的问题 - 默认情况下会选择第一个项目。此外,如果您不打算向该数组添加新项目,则可以使用ko.observable而不是ko.observableArray

更新: Knockoutjs似乎不喜欢具有相同值的多个选项。如果将值绑定添加到选择标记,我的代码将无法正常工作(它将选择第三项,而不是第一项)。但是,由于knockoutjs允许您访问所选对象(通过值绑定),您可以通过值绑定删除optionsValue绑定和访问值:jsfiddle.net/ej9Ue/1