在 View 模型中考虑以下属性

self.allValues = ko.observableArray();
self.selectedValues = ko.observableArray();

在编辑时,selectedValues包含来自数据库的值。这是问题所在:selectedValues包含的元素比allValues包含的元素多,但它们是而不是相同的实例。从属性值的 Angular 来看,它们是相同的,但实际上是不同的对象。

这导致每次 knockout 操作使用indexOf而不是allValues时,使用selectedValues中的对象总是找不到对象。

我在selectedValues绑定(bind)上使用checked,但是无法检查此数组中包含的正确元素。
<div class="vars-list" data-bind="foreach: allValues">
    <input type="checkbox" data-bind="checkedValue: $data...(etc)
       checked: selelectedValues"  />
</div>

有什么方法可以通过剔除属性值而不是内存地址来匹配对象?

最佳答案

使用自定义绑定(bind)是一种方法。这是使用比较功能的checked绑定(bind)的一种变体。

ko.bindingHandlers.checkedInArray = {
    init: function (element, valueAccessor, allBindings) {
        ko.utils.registerEventHandler(element, "click", function() {
            var observable = valueAccessor(),
                array = observable(),
                checkedValue = allBindings.get('checkedValue'),
                isChecked = element.checked,
                comparer = allBindings.get('checkedComparer');

            for (var i = 0, n = array.length;
                i < n && !comparer(array[i], checkedValue);
                ++i) { }

            if (!isChecked && i < n) {
                observable.splice(i, 1);
            } else if (isChecked && i == n) {
                observable.push(checkedValue);
            }
        });
    },
    update: function (element, valueAccessor, allBindings) {
        var array = valueAccessor()(),
            checkedValue = allBindings.get('checkedValue'),
            comparer = allBindings.get('checkedComparer');

        for (var i = 0, n = array.length;
            i < n && !comparer(array[i], checkedValue);
            ++i) { }

        element.checked = (i < n);
    }
};

jsFiddle:http://jsfiddle.net/mbest/4mET9/

07-24 22:03