我有一个observableArray,它看起来像这样:
this.menuItems = ko.observableArray([
{ name: "level1", subItems: [
{ name: "level1-1" },
{ name: "level1-2" }
] },
{ name: "level2" },
{ name: "level3", subItems: [
{ name: "level3-1" },
{ name: "level3-2", subItems: [
{ name: "level3-2-1" }
] },
] },
{ name: "level4" }
]);这将呈现多级导航菜单。因此,有些项目可以有subItems,而另一些则没有,并且级别的数量是未知的。
现在我有了一个“过滤器导航”输入来过滤这些东西。
var self = this,
menuFilter = ko.observable(""),
filter = menuFilter().toLowerCase();
if (filter === "") {
return self.menuItems();
} else {
return ko.utils.arrayFilter(self.menuItems(), function (item) {
if (item.name.toLowerCase().indexOf(filter) !== -1) {
return true;
}
});
}这对于顶级项目非常有用,但我不确定通过self.menuItems().subItems循环的最佳方法,然后是下一个级别,然后是下一个级别,等等。
有什么想法吗?
编辑:,我刚刚创建了这个JS,它似乎正在工作。现在我必须想办法让它在我稍微复杂的应用程序上运行。
http://jsfiddle.net/KSrzL/7/
编辑(再次):我最近的问题是顶层没有信息,所以我必须从.children开始,因为它不起作用。
http://jsfiddle.net/KSrzL/8/
发布于 2013-05-30 21:40:20
这似乎很有效:http://jsfiddle.net/MRtRm/
关键部分:
self.nonNullItems = function(arr) {
return arr.filter(function(x) { return x !== null; });
};
self.filteredObjectOrNull = function(obj, query) {
if (obj.hasOwnProperty('children')) {
var filteredChildren = self.nonNullItems(obj.children.filter( function(x) { return self.filteredObjectOrNull(x, query); }));
if (filteredChildren.length > 0)
return {name: obj.name, children: filteredChildren};
}
if (self.matchText(obj.name, query))
return obj;
return null;
};
self.filterItems = function() {
var filter = self.itemFilter();
if (filter === "") {
return self.items();
} else {
return self.nonNullItems(self.items().map( function(x) { return self.filteredObjectOrNull(x, filter); }));
}
}我认为它可以通过几种方式简化,但它似乎通过了我所做的测试。(您应该再添加几个级别的菜单来确保。)
https://stackoverflow.com/questions/16845003
复制相似问题