我试图使用Knockout js过滤嵌套的json数组。以下是我的JSON外观
{
"groups": [{
"name": "Category1",
"items": [{
"question": "Question1",
"answer": "Answer1"
}]
}, {
"name": "Category2",
"items": [{
"question": "Question2",
"answer": "Answer2"
}, {
"question": "Question3",
"answer": "Answer3"
}]
}]
}
我需要根据“答案”进行过滤。以下是我的HTML页面现在的样子
<div >
<div class="groups" data-bind="{foreach: {data: filteredGroups, as: 'group'}}">
<div class="name-row" data-bind="text: group.name"></div>
<div class="items" data-bind="{foreach: {data: group.items, as: 'item'}}">
<div class="item-row">
<div class="question-row">
<div class="question-content">
<div class="letter">Question</div>
<div data-bind="text: item.question"></div>
</div>
<div class="notch"> </div>
</div>
<div class="answer-row">
<div class="letter">Answer</div>
<div data-bind="text: item.answer"></div>
</div>
</div>
</div>
</div>
以下是我目前的逻辑:
self.filteredGroups = ko.computed(function() {
if (!self.query()) {
return self.groups();
}
else {
var matchCount = 0;
return ko.utils.arrayFilter(self.groups(), function(group) {
return ko.utils.arrayFilter(group.items, function(item) {
//console.log("Entered==>" + self.query().toLowerCase() + " " + "Search==>" + item.question.toLowerCase());
var found = item.answer.toLowerCase().indexOf(self.query().toLowerCase());
if(found >= 0){
console.log("Number of occurrences" +matchCount++);
return true;
}else{
return false;
}
});
});
}
});
然而,当我尝试执行相同的操作时,我没有得到过滤结果。有什么我想念的吗?
答案 0 :(得分:3)
我想你想要保留他们的小组来过滤项目。在您的解决方案中,内部arrayFilter
将始终返回一组过滤的项目。但是你可能知道任何数组(甚至是空的)总是会评估为true
,导致外部arrayFilter
使用 all 返回所有原始组对象原始项目,因为过滤的项目由于隐式类型转换而丢失。
让computed
工作的最简单方法:
self.filteredGroups = ko.computed(function() {
if (!self.query()) {
return self.groups();
} else {
var result = [];
// for each group
ko.utils.arrayForEach(self.groups(), function(group){
// find items matching the query
var items = ko.utils.arrayFilter(group.items, function(item){
return item.answer.toLowerCase().indexOf(self.query()) >= 0;
}); console.log(items);
// if found something then push new group object with filtered items
if (items.length > 0) result.push({
name: group.name,
items: items
});
});
return result;
}
});