KnockoutJS selectedOptions未显示

时间:2015-01-12 19:43:04

标签: javascript html knockout.js

我正在使用KnockoutJS来管理我的网络前端。我正在编写一个CRUD / Admin站点,但我遇到了selectedOptions绑定问题。

案例:

  • 视图模型包含form.products.allform.products.selected个可观察对象。这两个都是由ko.mapping生成的。

  • HTML表单有多种形式选择:

    <select required="" multiple="" data-bind="options: products.all, optionsText: function (item) { return item.value.name.unName(); }, selectedOptions: products.selected" class="form-control">
    
  • HTML表单正确显示了所有选项。

  • HTML表单在加载时显示所选选项。特别是,如果我检查viewModel对象,我可以看到正确的对象在加载时被加载到products.selected数组中。但是多选不会自动选择它们。

  • 如果我在表单中选择对象然后检查products.selected可观察对象,我执行查看数组中的对象。

  • 如果我发布表单,正确的对象最终会进入数据库,然后在下一页加载的viewModel对象中结束(因此循环中唯一缺少的部分实际上是基于表单标记表单) products.selected

  • 中的内容

我做错了什么?我看到了相互矛盾的建议,其中一些已经过时,所以我不确定如何继续。

1 个答案:

答案 0 :(得分:2)

selectedOptions绑定按设计工作。

您的selected observable很可能不包含相同的对象(即引用all中的对象) ,但仅仅是具有相同属性值的对象。

Knockout通过对象标识维护绑定,它不进行任何其他比较。

考虑这个简单的例子:

var vm = {
    products: {
        selected: ko.observableArray(),
        all: ko.observableArray([
            {
                value: {
                    name: {
                        unName: ko.observable("Foo")
                    }
                }
            }, {
                value: {
                    name: {
                        unName: ko.observable("Bar")
                    }
                }
            }
        ])
    }
};
vm.products.selected.push(vm.products.all()[1]);
ko.applyBindings(vm);
pre {
  font-size: small;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>

<select required="" multiple="" class="form-control" data-bind="
    options: products.all, 
    optionsText: function (item) { 
        return item.value.name.unName(); 
    }, 
    selectedOptions: products.selected
"></select>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>


不相关的附注:尽量避免在绑定属性中定义函数。它是丑陋的,低效的,可能重复的,并不是非常惯用的。在视图模型上创建相应的属性,例如:

function Product(data) {
    ko.utils.extend(this, data);
    this.displayName = this.value.name.unName;
}

<div data-bind="with: products">
    <select required="" multiple="" class="form-control" data-bind="
        options: all, 
        optionsText: 'displayName', 
        selectedOptions: selected
    "></select>
</div>