如何使用Knockout.js移除对象数组重复项并实现视图绑定
Knockout.js 数组去重与下拉框绑定实现
问题说明
现有包含重复对象的数组:
var ticketgroups = [ {TicketGroup: TicketGroup1, SortOrder: 1}, {TicketGroup: TicketGroup1, SortOrder: 1}, {TicketGroup: TicketGroup2, SortOrder: 2}, {TicketGroup: TicketGroup2, SortOrder: 2}, {TicketGroup: TicketGroup3, SortOrder: 3}, {TicketGroup: TicketGroup3, SortOrder: 3}, ];
需要用Knockout.js将其去重为如下数组:
var filtered = [ {TicketGroup: TicketGroup1, SortOrder: 1}, {TicketGroup: TicketGroup2, SortOrder: 2}, {TicketGroup: TicketGroup3, SortOrder: 3}, ];
同时要实现下拉框的视图绑定,原始绑定代码如下:
<select id="customticketgroup" data-bind="options: $root.filtered.TicketGroup"/>
实现方案
1. 数组去重逻辑
可以用原生JavaScript的过滤逻辑,配合Knockout的computed属性实现响应式的去重数组——这样原始数组变化时,去重后的数组会自动更新:
function ViewModel() { var self = this; // 把原始数组转为Knockout可观察数组 self.ticketgroups = ko.observableArray([ {TicketGroup: 'TicketGroup1', SortOrder: 1}, {TicketGroup: 'TicketGroup1', SortOrder: 1}, {TicketGroup: 'TicketGroup2', SortOrder: 2}, {TicketGroup: 'TicketGroup2', SortOrder: 2}, {TicketGroup: 'TicketGroup3', SortOrder: 3}, {TicketGroup: 'TicketGroup3', SortOrder: 3}, ]); // 计算属性:生成去重后的数组 self.filtered = ko.computed(function() { var uniqueKeys = {}; return self.ticketgroups().filter(function(item) { // 用TicketGroup+SortOrder的组合作为唯一标识,避免漏判 var key = `${item.TicketGroup}-${item.SortOrder}`; if (!uniqueKeys[key]) { uniqueKeys[key] = true; return true; } return false; }); }); } // 激活ViewModel,绑定到页面 ko.applyBindings(new ViewModel());
2. 修正下拉框绑定
原始绑定代码存在错误:filtered是数组,不能直接通过.TicketGroup访问元素属性。需要调整绑定规则,用options指定去重后的数组,optionsText指定要显示的字段:
<select id="customticketgroup" data-bind="options: $root.filtered, optionsText: 'TicketGroup'"/>
如果需要把选中的项绑定到ViewModel的属性,可以添加value绑定:
<select id="customticketgroup" data-bind="options: $root.filtered, optionsText: 'TicketGroup', value: selectedGroup"/>
对应的ViewModel里要新增可观察属性:
self.selectedGroup = ko.observable();
内容的提问来源于stack exchange,提问作者user3774591
相关产品推荐
相关产品推荐

