我对实例化集合的时间和地点感到有点困惑,并在骨干应用程序中获取它们。
我已经看到它现在已经完成了几个方面,并且在我非常简单的小CRUD联系人管理器应用程序中工作了我很乱,但我确信有一些约定和'陷阱'我不是意识到了。
这些是我看过的选项,要么已经开始工作,要么就是“工作”了:)选项4似乎是概念上最好的,但是我把它搞砸了。
糟糕的想法:1)在我真正对路由器做任何事情之前,我实例化了一个新的集合并调用了fetch,然后在doc ready语句中启动了app.view。
// Create an Instance of the collection
App.contacts = new App.Collections.Contacts;
App.contacts.fetch({update: true, remove: false}).then(function() {
new App.Views.App({ collection : App.contacts });
});
BAD IDEA:2)当我开始使用路由器时,我想在路由器init方法中做同样的事情,这也很有用,但我认为这给我留下了同样的问题。
坏想法:3)我尝试在集合中使用init方法,虽然我在很多地方读过这个但这个想法很糟糕。
好想法(?):但我不能让它工作:4)我想,当我实例化它的View时,获取集合的数据是有意义的,这样如果我有一个联系人集合和一个任务集合,当我在路由器中实例化它的视图时,每个集合都只会从服务器中取出。这对我来说似乎是一个成功的公式,但是当我试图将它放在View init或渲染方法中时,我this.collection.on('add', this.addOne, this);
给了我不能调用.on on undefined。 (注意:我试过把它放在成功函数中)
我正在努力,请帮助。
干杯。
编辑:附加代码,以便我们可以诊断下面讨论的双重负载。
在我的路由器文件中,我正在使用此实用程序obj:
var ViewManager = {
currentView : null,
showView : function(view) {
if (this.currentView !== null && this.currentView.cid != view.cid) {
this.currentView.remove();
}
this.currentView = view;
return view;
}
}
在我的路由器中:我在路线上调用此方法
list: function() {
console.log('backbone loading list route');
var AllContactsView = new App.Views.Contacts({ //init method runs now
collection : App.contacts
});
ViewManager.showView(AllContactsView);
},
我的收藏
App.Collections.Contacts = Backbone.Collection.extend({
model: App.Models.Contact,
url: 'contacts',
});
在我看来
App.Views.Contacts = Backbone.View.extend({
tagName: 'tbody',
initialize: function() {
this.listenTo(this.collection, 'sync', this.render);
this.listenTo(this.collection, 'add', this.addOne);
this.collection.fetch({
// update: true,
// remove: false
});
},
render: function() {
// append the list view to the DOM
$('#allcontacts').append(this.el);
// render each of the single views
this.collection.each( this.addOne, this);
return this;
},
addOne: function(contact) {
var contactView = new App.Views.Contact({ model: contact});
this.$el.append(contactView.render().el);
}
});
在我的app.js
中// Run App
jQuery(document).ready(function($) {
// Create an Instance of the collection
App.contacts = new App.Collections.Contacts;
// Init BB Router
new App.Router.Route;
Backbone.history.start(); // Kick it all off.
});
答案 0 :(得分:1)
您的观点应该是这样的:
App.Views.Contacts = Backbone.View.extend({
tagName: 'tbody',
initialize: function() {
this.listenTo(this.collection, 'reset', this.render);
this.listenTo(this.collection, 'add', this.addOne);
vent.on('contactR:closeAll', this.closeView, this);
this.collection.fetch();
},
});
答案 1 :(得分:0)
所以我实现了我的错误,因为那个讨厌的小this
关键词melarky,所以现在它是一个风格或概念性的问题
可能在我的设置文件中调用路由器之前。
App.contacts = new App.Collections.Contacts;
在我的路由器中:
list: function() {
var AllContactsView = new App.Views.Contacts({
collection : App.contacts
});
ViewManager.showView(AllContactsView);
},
在视图中:
App.Views.Contacts = Backbone.View.extend({
tagName: 'tbody',
initialize: function() {
var that = this;
this.collection.fetch({ update: true, remove: false}).then(function() {
that.collection.on('add', that.addOne, that);
vent.on('contactR:closeAll', that.closeView, that);
that.render();
});
},
});
这对我来说似乎更灵活,在概念上对我来说更合适,但我会喜欢这个答案的反馈。
答案 2 :(得分:0)
因此,似乎让render方法中的.each有点无意义,因为在fetch连接成功并且在触发sync事件之前,add事件会触发。因此,add事件的listenTo会在需要时触发addOne,而render事件现在只是将集合附加到dom同步。
App.Views.Contacts = Backbone.View.extend({
tagName: 'tbody',
initialize: function() {
this.listenTo(this.collection, 'sync', this.render);
this.listenTo(this.collection, 'add', this.addOne);
this.collection.fetch();
},
render: function() {
// append the list view to the DOM
$('#allcontacts').append(this.el);
/*
render each of the single views - removing this seems to set everything
right in the world
*/
// this.collection.each( this.addOne, this);
return this;
},
addOne: function(contact) {
var contactView = new App.Views.Contact({ model: contact});
this.$el.append(contactView.render().el);
}
});
答案 3 :(得分:0)
因此经过大量的谷歌搜索,阅读和测试后,我已经完成了以下工作。我不认为这是最优的,因为我们迫使主干运行其重置事件,这似乎是在大多数示例应用程序中完成它的方式,虽然我觉得这忽略了默认行为已更改的事实,当然这是有原因的吗?
最终这种方法目前有效,但我会非常高兴看到另一种选择。
/*Collection view
- - - - - - -*/
App.Views.Contacts = Backbone.View.extend({
tagName: 'tbody',
initialize: function() {
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'reset', this.addAll);
this.listenTo(this.collection, 'all', this.render);
this.collection.fetch({reset:true});
},
render: function() {
// append the list view to the DOM
$('#allcontacts').append(this.el);
return this;
},
addAll : function() {
this.collection.each( this.addOne, this);
},
addOne: function(model) {
var contactView = new App.Views.Contact({ model: model});
this.$el.append(contactView.render().el);
}
});
我有这个实用程序,我已将调用添加回到:
var ViewManager = {
currentView : null,
showView : function(view) {
if (this.currentView !== null && this.currentView.cid != view.cid) {
this.currentView.remove();
}
this.currentView = view;
return view.render();
}
}
在我的路由器中,我在列表路径上调用它:
list: function() {
console.log('backbone loading list route');
var AllContactsView = new App.Views.Contacts({ //init method runs now
collection : App.contacts
});
ViewManager.showView(AllContactsView);
},
正如我所说,我觉得可能会有一两个小问题,但它现在可以在我的应用程序中运行,我将在稍后阶段再次回到它。无可争议。