Display knockouts from multiple sources in one list without deleting unregistered items

I have two lists of data and you want to combine them into one list with a knockout display.

This seems like normal if I define a key to compare, except that it removes items not listed in the last update.

Is it possible to use KO Mapping for an array without deleting elements that are not found in the last list?

EG below should be done:

  • 1 AB
  • 2 AA BB
  • 3 AAA
  • 4 BBB

not

  • 1 AB
  • 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/

+4
source share
3 answers

I know this question is quite old, so it may not help Luke, but it may help others who come here from Google (like me). I recently had a similar problem, and they helped me in a knockout forum: https://groups.google.com/forum/#!topic/knockoutjs/22DzjfgUzMs

Good luck

+1
source

What prevents you from using Computed Observable to create this behavior?

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

Will something like this satisfy your needs?

  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. 

I had to add a dependency on jquery to do the above work, however the principle is the same if you remove confidence in jquery. Matching did not solve this problem, since the key would be used to remove items that do not appear in ListB.

0
source

Source: https://habr.com/ru/post/1493568/


All Articles