在不删除未列出项目的情况下,将多个源的映射删除到单个列表中

Knockout mapping from multiple sources into a single list without removing unlisted items

本文关键字:删除 映射 单个 列表 未列出 项目 情况下      更新时间:2023-09-26

我有两个数据列表,希望将它们合并到一个带有淘汰映射的列表中。

如果我定义了一个要进行比较的键,这似乎可以正常工作,只是它删除了最近更新中未列出的项。

有没有一种方法可以在不删除最新列表中没有出现的项的情况下使用KO映射到数组

EG以下,应产生:

  • 1 A B
  • 2 AA BB
  • 3 AAA
  • 4 BBB

不是

  • 1 A B
  • 2 AA BB
  • 4 BBB


    <ul data-bind='foreach: mergedList'>
        <li>
            <span data-bind='text: id'></span>
            <span data-bind='text: a'></span>
            <span data-bind='text: b'></span>
        </li>
    </ul>

    var listA = [
        { id: 1, a: 'A'},
        { id: 2, a: 'AA'},
        { id: 3, a: 'AAA'}
    ];
    var listB = [
        { id: 1, b: 'B'},
        { id: 2, b: 'BB'},
        { id: 4, b: 'BBB'}
    ];
    var mapping = {
        key: function(data) {
            return ko.utils.unwrapObservable(data.id);
        },
        create: function (options){
            var model = new subViewModel();
            ko.mapping.fromJS(options.data, {}, model);
            return model;
        }
    }
    var subViewModel = function(){
        var self = this;
        self.a = ko.observable();
        self.b = ko.observable();
    }
    var viewModel = function(){
        var self = this;
        self.mergedList = ko.observableArray();
    }
    var vm = new viewModel();
    ko.mapping.fromJS(listA, mapping, vm.mergedList);
    ko.mapping.fromJS(listB, mapping, vm.mergedList);
    ko.applyBindings(vm);

http://jsfiddle.net/BQRur/9/

我知道这个问题很老了,所以这可能对Luke没有帮助,但可能会帮助其他从谷歌来的人(比如我)。我最近也遇到了类似的问题,并在淘汰赛论坛上得到了帮助:https://groups.google.com/forum/#!主题/knockoutjs/22DzjfgUzMs

祝你好运!

是什么阻止您使用Computed Observable来产生这种行为?

ko.mapping.fromJS(listA,mapping,vm.listA);
ko.mapping.fromJS(listB,mapping,vm.listB);
vm.mergedList= ko.computed(function(){
return listA().concat(listB());
});

这样的东西适合你的需求吗?

    var listA = ko.observableArray([
        { id: 1, a: 'A'},
        { id: 2, a: 'AA'},
        { id: 3, a: 'AAA'}
    ]);
    var listB = ko.observableArray([
        { id: 1, b: 'B'},
        { id: 2, b: 'BB'},
        { id: 4, b: 'BBB'}
    ]);
    function viewModel () {
        var self = this;
        self.mergedList = ko.computed(function () {
            var result = [];
            // Build an associative array, ensure the object shape is defined as a default, or the bindings will fail on the missing entries (id 3 missing b, id 4 missing a).
            $.each(listA().concat(listB()), function (i, o) {
                result[o.id] = $.extend({}, result[o.id] || { id: null, a: null, b: null }, o);
            });
            // Extract only the entries from the associative array.
            result = $.map(result, function (o) {
                return o;
            });
            return result;
        });
    }
    var vm = new viewModel();
    ko.applyBindings(vm);
    // Async requests to update listA / listB here.

我不得不添加一个对jquery的依赖来实现上述功能,但是,如果去掉对jquery的依赖,原理是一样的。映射并不能解决这个特定的问题,因为密钥将用于删除列表B中没有出现的项。