Backbone Views inside Collections
我对Backbone 网还很陌生,需要使用它来创建列表项。每个列表项都有一个模型和一个视图。因为它是列表,所以它似乎是集合的理想解决方案,但我一直在努力使用它们。
这是当前版本,我想更改使用版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // The Model & view var IntroModel = Backbone.Model.extend({}); var Introview = Backbone.View.extend({ template: _.template( $('#taglist-intro').text() ), render: function() { console.log( this.model.attributes ); this.$el.append( this.template( this.model.attributes ) ); } }); // We will store views in here // Ideally this would be a collection views = []; // Get the data for that collection $.getJSON( url, function( json ) { _.each( json, function( item ) { // Create each model & view, store views in the views array var model = new IntroModel( item ); var view = new Introview({ model : model }) views.push( view ); }) }) // I can render a view like this // But I'd rather it rendered the view when I add items to the collection views[0].render() |
所以我的作品行得通,但它并不是真正做到的"Backbone 方式"。这似乎没有什么意义,因为:
感谢任何指针,如果您不能提供特定的代码示例,我仍然非常感谢链接
您认为当前的实现不是Backbone方式。您正在执行的大多数操作都是由主干中的collection对象直接处理的。在主干集合中,本质上只是一个数组,附加了其他方法。这些方法使馆藏具有强大的功能。Backbone 网具有许多功能,包括:
- 'url'属性:使用此属性,当您运行fetch方法(例如myCollection.fetch())时,集合会自动填充自身。
- 您可以将函数绑定到集合的"重置"事件。当您填充集合时,将触发此事件。通过包含对集合的render事件的调用,您的集合可以在集合发生更改时自动呈现相关视图。您还可以将函数附加到其他收集事件(例如,"添加"新模型等)。
-
我发现Backbone文档是最好的起点。但是,一个简单的示例总是有用的。以下代码显示了如何定义一个简单的集合,以及如何创建两个视图(一个视图创建一个列表,另一个视图在列表中呈现该项目)。请注意集合中url属性的使用。当您运行fetch()方法(请参阅OrgListView对象)时,Backbone使用它来检索集合的内容。还要注意,视图的render方法如何绑定到集合的" reset"事件,这确保了在填充集合之后调用render事件(请参见OrgsListView的initialize方法)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88/**
* Model
*/
var Org = Backbone.Model.extend();
/**
* Collection
*/
var Orgs = Backbone.Collection.extend({
model: Org,
url: '/orgs.json'
});
/**
* View - Single Item in List
*/
var OrgItemView = Backbone.View.extend({
tagName: 'li',
initialize: function() {
_.bindAll(this, 'onClick', 'render');
this.model = this.options.model;
// Create base URI component for links on this page. (e.g. '/#orgs/ORG_NAME')
this.baseUri = this.options.pageRootUri + '/' + encodeURIComponent(this.model.get('name'));
// Create array for tracking subviews.
/*var subViews = new Array();*/
},
events: {
'click a.test': 'onClick'
},
onClick: function(event) {
// Prevent default event from firing.
event.preventDefault();
if (typeof this.listContactsView === 'undefined') {
// Create collection of contacts.
var contacts = new ContactsByOrg({ url: '/orgs.json/' + encodeURIComponent(this.model.get('name')) });
this.listContactsView = new ListContactsView({ collection: contacts, baseUri: this.baseUri });
this.$el.append(this.listContactsView.render().el);
}
else {
// Close View.
this.listContactsView.close();
// Destroy property this.listContactsView.
delete this.listContactsView;
}
},
onClose: function() {
// console.log('Closing OrgItemView');
},
render: function() {
// TODO: set proper value for href. Currently using a dummy placeholder
this.$el.html('' + this.model.get('name') + '');
return this;
}
});
/**
* View - List of organizations
*/
var OrgsListView = Backbone.View.extend({
className: 'orgs-list',
initialize: function() {
console.log('OrgsListView');
_.bindAll(this, 'render');
this.pageRootUri = this.options.pageRootUri;
this.collection = this.options.collection;
// Bind render function to collection reset event.
this.collection.on('reset', this.render);
// Populate collection with values from server.
this.collection.fetch();
},
onClose: function() {
this.collection.off('reset', this.render);
// console.log('Closing OrgsListView');
},
render: function() {
var self = this;
this.$el.html('
<ul>
</ul>
');
this.collection.each(function(org, index) {
var orgItemView = new OrgItemView({ model: org, pageRootUri: self.pageRootUri });
self.$('ul').append(orgItemView.render().el);
});
return this;
}
});