有人可以帮帮我吗?
如何让多选列表具有唯一的国家/地区?另外,如何根据多选中选择的项目过滤记录?
以下是JsFiddle http://jsfiddle.net/B2xcv/
中的代码请帮忙。
感谢。
HTML 的
<div class='liveExample'>
<p style="color:red">How do I make this list unique?</p>
<p>
<select data-bind="options: people,optionsText: 'country', selectedOptions: selectedCountries" size="5" multiple="true" style="width:150px"></select>
</p>
<p style="color:red">And how do I filter the records below based on the selected items above? (multiple select)</p>
<table style="width:300px">
<thead>
<th>Name</th>
<th>Location</th>
</thead>
<tbody data-bind="foreach: people">
<tr>
<td>
<span data-bind="text: name"> </span>
</td>
<td>
<span data-bind="text: country"> </span>
</td>
</tr>
</tbody>
</table>
</div>
KnockoutJS
// Define a "Person" class that tracks its own name and children, and has a method to add a new child
var Person = function(name, country) {
this.name = name;
this.country = country;
}
// The view model is an abstract description of the state of the UI, but without any knowledge of the UI technology (HTML)
var viewModel = {
people: [
new Person("Annabelle", "UK"),
new Person("Bertie", "UK"),
new Person("Bertie", "USA"),
new Person("Ali", "Bangladesh"),
new Person("Patel", "India"),
new Person("Sweatha", "India"),
new Person("Minto", "India"),
],
selectedCountries: ko.observableArray()
};
ko.applyBindings(viewModel);
答案 0 :(得分:5)
好的 - 最简单的方法是创建变量来表示人物阵列的唯一国家和过滤版本。
如果people
是observableArray,那么您可能希望uniqueCountries
变量是计算的。如果它不可观察,那么你可以直接计算它。
以下是一个示例:
viewModel.uniqueCountries = ko.computed(function() {
var people = viewModel.people(),
index = {},
uniqueCountries= [],
length = people.length,
i, country;
for (i = 0; i < length; i++) {
country = people[i].country;
if (!index[country]) {
index[country] = true;
uniqueCountries.push(country);
}
}
return uniqueCountries;
});
主要思想是在所有人中进行一次循环,并建立一系列独特的国家。为此,我只使用一个“索引”对象,以便我可以轻松检查我们是否已经包含了这个国家(没有循环我们正在构建的列表)。然后,您可以将唯一的国家/地区作为数组返回,并在您的选择中绑定它。
接下来,您需要创建一个计算的observable来表示people
的过滤版本。这是一个示例:
viewModel.filteredPeople = ko.computed(function() {
var selected = viewModel.selectedCountries() || [],
index = {};
//build an index, so we can avoid looping each time
ko.utils.arrayForEach(selected, function(country) {
index[country] = true;
});
return ko.utils.arrayFilter(viewModel.people(), function(person) {
return index[person.country];
});
});
我再次构建了一个索引,因为您可以选择多个国家/地区。这样可以轻松检查此人的国家/地区是否属于所选国家/地区。 ko.utils.arrayFilter
将允许我们对数组中的每个项运行一个函数,并返回一个新数组,其中包含函数返回“truthy”值的任何项。我再次假设people
是一个observableArray,你可能正在添加/删除项目。
以下是更新后的示例:http://jsfiddle.net/rniemeyer/xsfRR/
答案 1 :(得分:2)
我知道这可能有点晚了但对于任何有兴趣的人我都这样做,使用ko内置函数:
var viewModel = {
people: [
new Person("Annabelle", "UK"),
new Person("Bertie", "UK"),
new Person("Bertie", "USA"),
new Person("Ali", "Bangladesh"),
new Person("Patel", "India"),
new Person("Sweatha", "India"),
new Person("Minto", "India"),
],
selectedCountries: ko.observableArray(),
uniqueCountries: function(){
var countries =ko.utils.arrayMap(viewModel.people,function(person){
return person.country;
});
return ko.utils.arrayGetDistinctValues(countries);
},
filteredRecords: function(){
return ko.utils.arrayFilter(viewModel.people,function(person){
return person.country == viewModel.selectedCountries();
});
}
};
ko.applyBindings(viewModel);
和html
<div class='liveExample'>
<p style="color:red">How do I make this list unique?</p>
<p>
<select data-bind="options: uniqueCountries(), selectedOptions: selectedCountries" size="5" multiple="true" style="width:150px"></select>
</p>
<p style="color:red">And how do I filter the records below based on the selected items above? (multiple select)</p>
<table style="width:300px">
<thead>
<th>Name</th>
<th>Location</th>
</thead>
<tbody data-bind="foreach: filteredRecords()">
<tr>
<td>
<span data-bind="text: name"> </span>
</td>
<td>
<span data-bind="text: country"> </span>
</td>
</tr>
</tbody>
</table>
</div>
在jsfiddle http://jsfiddle.net/geomorillo/n5JFL/1/
中答案 2 :(得分:0)
self.filterGrid = ko.computed(function () {
var text = filter().toLowerCase();
if (!text ) {
return self.filterArrayCollection();
}
else {
if (self.filterArrayCollection() != 'undefined' && self.filterArrayCollection() != null && self.filterArrayCollection().length > 0) {
return ko.utils.arrayFilter(self.filterArrayCollection(),
function (item) {
return (item.name.toLowerCase().indexOf(text) > -1 || item.address.toLowerCase().indexOf(text) > -1);
});
};
};
});