我的Backbone应用程序中有几个地方需要对集合进行即时搜索,但我很难想出最佳实现方式。
这里是一个快速的实现。 http://jsfiddle.net/7YgeE/ 请记住我的集合可能包含多达200个模型。
var CollectionView = Backbone.View.extend({
template: $('#template').html(),
initialize: function() {
this.collection = new Backbone.Collection([
{ first: 'John', last: 'Doe' },
{ first: 'Mary', last: 'Jane' },
{ first: 'Billy', last: 'Bob' },
{ first: 'Dexter', last: 'Morgan' },
{ first: 'Walter', last: 'White' },
{ first: 'Billy', last: 'Bobby' }
]);
this.collection.on('add', this.addOne, this);
this.render();
},
events: {
'keyup .search': 'search',
},
// Returns array subset of models that match search.
search: function(e) {
var search = this.$('.search').val().toLowerCase();
this.$('tbody').empty(); // is this creating ghost views?
_.each(this.collection.filter(function(model) {
return _.some(
model.values(),
function(value) {
return ~value.toLowerCase().indexOf(search);
});
}), $.proxy(this.addOne, this));
},
addOne: function(model) {
var view = new RowView({ model: model });
this.$('tbody').append(view.render().el);
},
render: function() {
$('#insert').replaceWith(this.$el.html(this.template));
this.collection.each(this.addOne, this);
}
});
每个模型都有一个小视图...
var RowView = Backbone.View.extend({
tagName: 'tr',
events: {
'click': 'click'
},
click: function () {
// Set element to active
this.$el.addClass('selected').siblings().removeClass('selected');
// Some detail view will listen for this.
App.trigger('model:view', this.model);
},
render: function() {
this.$el.html('<td>' + this.model.get('first') + '</td><td>' + this.model.get('last') + '</td>');
return this;
}
});
new CollectionView;
问题 1
在每个键按下事件中,我会过滤集合,清空 tbody
,并呈现结果,从而为每个模型创建一个新视图。我刚刚创建了幽灵视图,是吗?最好销毁每个视图吗?或者我应该尝试管理我的 RowView
,只创建每个视图一次,并通过循环渲染结果来实现?在清空 tbody
后,RowViews
是否仍然具有其 el
,还是现在为空并需要重新呈现?
问题 2,模型选择
您会注意到我在我的RowView
中触发了自定义事件。我想在某个地方拥有一个详细视图来处理该事件并显示我模型的全部内容。当我搜索我的列表时,如果我的选择模型仍然在搜索结果中,我希望保持该状态并让它保留在我的详细视图中。一旦它不再在我的结果中,我就会清空详细视图。所以我肯定需要管理一个视图数组,对吗?我考虑过双向链接结构,其中每个视图指向它的模型,每个模型指向它的视图...但如果我将来要在我的模型上实现一个单例工厂,我就无法将其强加给模型。:/
那么管理这些视图的最佳方法是什么?
pick
函数。此外,我从未听说过throttle
函数,这也非常有用。 - savingersetElement
并不完全认同。在每次呈现时重新绑定事件似乎不太优雅。我从未见过这种嫁接技术,其中您在CollectionView中呈现列表项并嫁接ItemViews...我不习惯ItemView不负责自己的呈现,一方面似乎是不应该发生的关注点分离,但另一方面则出奇地直截了当,因为让模板迭代我们的集合总是更容易的。 - savingersetElement
主要用于美观和模板的“自包含性”,如果您需要重新渲染行,则此技术将更有用。这个答案可能会帮助您理解我的观点:https://dev59.com/Ymct5IYBdhLWcg3wjuEj#12006179 - nikoshr