gpt4 book ai didi

javascript - 如何过滤/搜索嵌套的 Backbone 集合?

转载 作者:行者123 更新时间:2023-11-30 05:32:57 25 4
gpt4 key购买 nike

我的 Backbone 应用程序中有一个 TreeView ,我使用嵌套的集合和模型:

收藏:

define(function(require) {

var Backbone = require('backbone')
, UserListModel = require('app/models/userList');

return Backbone.Collection.extend({
model: UserListModel,
url: '/api/lists',
});
});

型号:

define(function(require) {

var Backbone = require('backbone');

return Backbone.Model.extend({

constructor: function(data, opts) {
opts = _.extend({}, opts, {parse: true});

var UserLists = require('app/collections/userLists');
this.children = new UserLists();

Backbone.Model.call(this, data, opts);
},

parse: function(data) {
if (_.isArray(data.children))
this.children.set(data.children);
return _.omit(data, 'chilren');
}

});
});

View 的一部分:(此处为完整 View :http://laravel.io/bin/O9oYX)

var UserListTreeItemView = Backbone.View.extend({

render: function() {
var data = this.model.toJSON();
data.hasChildren = !!this.model.get('isFolder');

this.$el.html(this.template(data));

if( this.model.get('isFolder') ) {
var list = new UserListTreeView({
collection: this.model.children
});
this.$el.append(list.render().el);
}

return this;
}

});

我使用两个 View 将我的集合呈现为 TreeView 。我想在我的 TreeView 中添加一个搜索功能,但我不知道该怎么做。它应该能够搜索所有模型及其嵌套模型的 name 属性。

有什么想法吗?

最佳答案

如果您的集合中已经有了您想要的模型,只需对集合本身使用继承的 Underscore 方法 filter()。不过,它将返回模型数组,而不是主干集合。

http://underscorejs.org/#filter

假设按属性name过滤:

var nameToSearch = "whatever";
var itemsByName = this.model.children.filter(function(item){
return item.get("name").indexOf(nameToSearch) >=0;
}

我要做的是隔离您的 getData 方法以涵盖这两种情况:打开/关闭过滤。

您没有指定搜索方式,但我假设您周围有文本输入并且您想使用该值。只会搜索 HitTest 门的项目吗?深度搜索会稍微复杂一些,涉及到每个父项以查找其子项的名称。对于您要在每个文件夹中搜索文件的简单情况,请将搜索过滤器保持在您的父 View 状态。为此,我通常使用普通的主干模型,只是为了利用事件。

var MySearchView = Backbone.View.extend({
initialize: function(options){
//I like the idea of having a ViewModel to keep state
this.viewState = new Backbone.Model({
searchQuery: ""
});
//whenever the search query is changed, re-render
this.listenTo(this.viewState, "change:searchQuery", this.render);
},
events: {
"click .js-search-button": "doSearch"
},
doSearch: function(e){
e.preventDefault();
var query = this.$(".js-search-input").val();
this.viewState.set("seachQuery", query);
},
render: function(){
var data = this.model.toJSON();
data.hasChildren = !!this.model.get('isFolder');

this.$el.html(this.template(data));

if( this.model.get('isFolder') ) {
//be careful with this, you're not removing your child views ever
if(this._listView) {
this._listView.remove();
}
this._listView = new UserListTreeView({
collection: this.model.children,
**searchQuery: this.viewState.get("searchQuery")**
});
this.$el.append(this._listView.render().el);
}

return this;
}
});

现在在您的 UserListTreeView 中,将模板的数据馈送抽象为一个考虑搜索查询的方法:

var UserListTreeView = Backbone.View.extend({
initialize: function(options){
this.searchQuery = options.searchQuery || "";
},
...
getData: function(){
//filter your collection if needed
var query = this.searchQuery;
if(query !== ""){
return this.collection.filter(function(file){
return file.get("name").indexOf(query) >= 0;
}
else {
return this.collection.toJSON();
}
},
render: function() {
var items = this.getData(),
template = this.template(items);

this.$el.empty().append(template);
return this;
}
});

瞧,同一个 View 将呈现完整集合或筛选版本,其项目名称中包含 searchQuery。您可以通过更改 filter 调用中的比较来调整搜索方法:您可以执行 RegExp,仅搜索以 (indexOf(searchQuery) == 0) 开头的文件,等等。

用了比预期更长的时间,希望对您有所帮助。另一种选择是在集合本身中实现它,您可以覆盖其 toJSON() 方法以返回全部或其中的某些项目。如果您发现自己正在编写另一个需要 filterint 的 View ,那么创建一个 SearchableCollection 并从那里继承两者可能是更好的主意。保持干燥。 :)

作为旁注:您应该看看 MarionetteJS 或构建您自己的专门 View (Collection 等),以免一遍又一遍地输入相同的内容。

关于javascript - 如何过滤/搜索嵌套的 Backbone 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25746313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com