所以我对backbone.js真的很陌生,我想要了解基本概念,以获取零件(视图/模型/路线)与其他部分进行交互。
这是一个例子。我有一个'screen'模型对象,由'singleScreen'视图呈现给页面。我还有一个'侧边栏'模型和正在渲染的视图。当我点击侧边栏中的链接时,我想让它渲染一个不同的屏幕模型对象,并根据我给出我的屏幕模型的'name'属性在单独的html div(标题)中更改一些HTML。
所以第一个问题,是否应该在routes.js文件中完成重新呈现不同视图和更改标题html的所有代码?看起来这个文件会非常快。如果是这样,我如何得到我想在routes.js文件中呈现的模型对象的引用,以便我可以访问myModel.name(在app.js文件中实例化)等内容?
我是否将浏览器历史记录和我的视图呈现为单独的内容,并在我的app.js文件(我实例化所有对象的文件)中添加“链接被点击,呈现此”功能的代码?如果是这样的话,如果用户试图通过输入URL直接转到视图而不是点击?我的应用程序如何知道要渲染的内容?
或者,就我所知,这是最可能出现的情况,
我是否使用模型/视图的初始化函数来触发/监听单击链接时的事件(或者更改了backbone.history()?)并调用渲染?
我已经搞乱了所有3种方法,但无法理解如何将对象的引用传递给应用程序的其他部分,而不仅仅是将这些对象作为全局变量(这感觉非常错误)。
对于最后一个场景,我搞砸了各种事件,但我读过的每个地方都说你必须包含对它正在监听的对象的引用,这似乎打败了设置事件对象和监听的整个目的。一个事件,而不仅仅是查询该对象变量的状态......
例如。
this.listenTo(sidebarModel , "change:selected", this.render());
如何将对sidebarModel对象的引用传递给singleScreen视图,以便知道它应该被监听的内容。
我并不是真的在寻找一个编码的答案,更多的只是对最佳实践的理解以及如何完成事情。我觉得我很接近,但我知道我缺少/不理解的东西这就是为什么我自己无法弄明白这一点,所以对整个主题的一点点启发将不胜感激。谢谢。
答案 0 :(得分:1)
首先,您需要了解每个Backbone类的作用。首先阅读MVC可能有所帮助。
渲染视图时,模型不是必需的。它的作用是处理数据,可以是本地数据,也可以是API。影响数据的所有函数都应该在模型中,并且模型不应该具有与渲染相关的任何内容。
总会有异常,您可以使用模型处理仅与渲染相关的数据,但是当您发现此类情况时,您就会知道。
一个简单的例子就是一本书:
// The Book model class
var Book = Backbone.Model.extend({
idAttribute: 'code',
urlRoot: '/api/book'
});
// a Book instance
var solaris = new Book({ code: "1083-lem-solaris" });
从API中获取将调用:
// GET http://example.com/api/book/1083-lem-solaris
solaris.fetch(); // this is async
获取时,API返回JSON编码数据。
{
"code": "1083-lem-solaris",
"title": "Test title",
}
属性与现有属性合并,添加尚未存在的属性,并覆盖已存在的属性的值。
集合的作用是管理一组模型,这些模型同样可以是本地的,也可以从API中获取。它应该只包含与管理集合相关的功能。
var Library = Backbone.Collection.extend({
model: Book,
url: '/api/book'
});
var myLibrary = new Library();
// just adds an existing book to our array
myLibrary.add(solaris);
您可以获取一个集合以从API中获取现有图书数组:
myLibrary.fetch();
API应返回:
[
{ "code": "blah-code-123", "title": "Test title" },
{ "code": "other-code-321", "title": "Other book title" }
]
使用该集合创建新书并与API同步:
var myNewBook = myLibrary.create({ title: "my new book" });
这将发送带有属性的POST请求,API应返回:
{ "code": "new-code-123", "title": "my new book" },
视图处理其根DOM元素。它应该处理来自DOM的事件。它最适合用于包装小型组件并从较小的组件构建更大的组件。
将链接直接放在模板中,锚标记的href
中。没有必要使用事件。
<a href="#my-route">link</a>`
这是我如何渲染(简化)列表。
// book list item
var BookView = Backbone.View.extend({
tagName: 'li',
template: _.template('<a href="#book/<%= code %>"><%= title %></a>'),
initialize: function() {
// when the model is removed from the collection, remove the view.
this.listenTo(this.model, 'remove', this.remove);
},
render: function() {
this.$el.empty().append(this.template(this.model.toJSON()));
return this;
}
});
// book list
var LibraryView = Backbone.View.extend({
template: '<button type="button" class="lib-button">button</button><ul class="list"></ul>',
events: {
'click .lib-button': 'onLibButtonClick'
},
initialize: function(options) {
this.listenTo(this.collection, 'add', this.renderBook);
},
render: function() {
// this is a little more optimised than 'html()'
this.$el.empty().append(this.template);
// caching the list ul jQuery object
this.$list = this.$('.list');
this.collection.each(this.renderBook, this);
return this; // Chaining view calls, good convention http://backbonejs.org/#View-render
},
addItem: function(model) {
// Passing the model to the Book view
var view = new BookView({
model: model
});
this.$list.append(view.render().el);
},
onLibButtonClick: function() {
// whatever
}
});
路由器处理路由并且应该尽可能简单,以避免它变得太快太快。它可以获取集合和模型,或者视图可以处理它,这是模式的问题。
var LibraryRouter = Backbone.Router.extend({
routes: {
'*index': 'index',
'book/:code': 'bookRoute',
},
index: function() {
var library = new LibraryView({
el: 'body',
// hard-coded collection as a simple example
collection: new Library([
{ "code": "blah-code-123", "title": "Test title" },
{ "code": "other-code-321", "title": "Other book title" }
])
});
library.render();
},
bookRoute: function(code) {
var model = new Book({ code: code });
// here, I assume an API is available and I fetch the data
model.fetch({
success: function() {
var view = new BookPageView({
el: 'body',
model: model
});
view.render();
}
});
}
});
Backbone中的所有东西都有Events mixin,甚至是全局Backbone对象。因此,每个类都可以使用listenTo
将回调绑定到事件。
对Backbone中的所有内容进行深入研究将非常漫长,所以请提出问题,我会尝试扩展我的答案。