Javascript Backbonejs何时初始化集合
我正在用rails 3.1 mongodb和backbonejs构建一个小的单页应用程序 我有两个可以通过json api使用的资源。我在主干中创建了两个模型和集合,如下所示 我也有两个seprate路由器 项目路由器- notes路由器- 我从github使用backbonejs rails gem生成了它们,所以里面的代码只是一个模板。我在index.haml文件中初始化我的基本路由器Javascript Backbonejs何时初始化集合,javascript,ruby-on-rails,backbone.js,url-routing,Javascript,Ruby On Rails,Backbone.js,Url Routing,我正在用rails 3.1 mongodb和backbonejs构建一个小的单页应用程序 我有两个可以通过json api使用的资源。我在主干中创建了两个模型和集合,如下所示 我也有两个seprate路由器 项目路由器- notes路由器- 我从github使用backbonejs rails gem生成了它们,所以里面的代码只是一个模板。我在index.haml文件中初始化我的基本路由器 #projects :javascript $(function() { window.r
#projects
:javascript
$(function() {
window.router = new JsonApi.Routers.ProjectsRouter({projects: #{@projects.to_json.html_safe}});
new JsonApi.Routers.NotesRouter();
Backbone.history.start();
});
我不想在应用程序启动时获取注释,因为用户很可能永远不会查看注释内部。因此,没有充分的理由在开始时获取它。Inside NotesRouter在所有操作中,我依赖@notes变量,但没有.fetch()方法。此变量为空。此外,我应该可以从url复制notes视图,如
/1/notes/5
项目id=1
注_id=5
backbonejs中解决此类问题的最佳实践是什么?为什么不在请求时延迟加载笔记?下面是一个例子:
var State = Backbone.Model.extend({
defaults: {
ready: false,
error: null
}
});
var Note = Backbone.Model.extend({
initialize: function () {
this.state = new State();
}
});
var Notes = Backbone.Collection.extend({
model: Note,
initialize: function () {
this.state = new State();
}
});
var NoteCache = Backbone.Model.extend({
initialize: function () {
this._loading = false;
this._loaded = false;
this._list = new Notes();
},
_createDeferred: function (id) {
var note = new Note({ id: id });
this._list.add(note);
this._load();
return note;
},
getNote: function (id) {
return this._list.get(id) || this._createDeferred(id);
},
getNotes: function () {
if (!this._loaded)
this._load();
return this._list;
},
_load: function () {
var that = this;
if (!this._loading) {
this._list.state.set({ ready: false, error: null });
this._loading = true;
$.ajax({
url: '/api/notes',
dataType: 'json',
cache: false,
type: 'GET',
success: function (response, textStatus, jqXHR) {
_.each(response.notes, function (note) {
var n = that._list.get(note.id);
if (n) {
n.set(note);
} else {
that._list.add(note, { silent: true });
n = that._list.get(note.id);
}
n.state.set({ ready: true, error: null });
});
that._list.state.set({ ready: true, error: null });
that._list.trigger('reset', that._list);
that._loaded = true;
},
error: function (jqXHR, textStatus, errorThrown) {
that._list.state.set({ error: 'Error retrieving notes.' });
that._list.each(function (note) {
note.state.set({ error: 'Error retrieving note.' });
});
},
complete: function (jqXHR, textStatus) {
that._loading = false;
}
});
}
}
});
在本例中,我定义了一个NoteCache对象来管理延迟加载。我还向Note模型和Notes集合添加了一个“state”属性
您可能希望在某个位置(可能在路由内部)初始化NoteCache,并且无论何时需要一个或多个便笺,只需执行以下操作:
var note = noteCache.getNote(5);
var notes = noteCache.getNotes();
现在,在视图中,如果尚未加载便笺,则需要侦听状态更改:
var NoteView = Backbone.View.extend({
initialize: function(){
this.note.state.bind('change', this.render, this);
},
render: function(){
if (this.note.state.get('error') {
// todo: show error message
return this;
}
if (!this.note.state.get('ready') {
// todo: show loader animation
return this;
}
// todo: render view
return this;
}
});
我还没有对此进行测试,所以可能会有一些bug,但我希望您能理解。感谢您提供了一个非常好的示例,说明如何在backbone.js中构建延迟加载功能,但如果我有10个其他资源,如Note,该怎么办。我觉得我搞乱了backbone.js的低级部分。如果backbone.js不支持这个现成的特性,那么正确的模式可能就是获取所有可能的记录。你怎么想?我还发现这个线程有一些不错的插件。如果你有很多模型,你总是可以创建一个包含所有公共逻辑的基本缓存对象,并从中继承不同的缓存(例如BaseCache、NoteCache、UserCache等)。