我最近开始构建我的第一个Backbone.js项目,并且很难掌握如何处理单个项目的“个人视图”。
例如,如果我有一个由Backbone集合显示的todos列表。如果我想让应用程序提供链接并查看单个待办事项,我该如何处理?我会创建一个新类型的集合,并以某种方式按单个项目的ID过滤集合?这种逻辑会在哪里生活?在路由器内?
修改
我已经更新了我的路由器:
var Backbone = require('backbone');
var IndexListing = require('./indexlisting');
var BookView = require('./bookview');
var LibraryCollection = require('./library');
module.exports = Backbone.Router.extend({
routes: {
'': 'allBooks',
'book/:id': 'singleBook'
},
allBooks: function(){
new IndexListing({
el: '#main',
collection: LibraryCollection
}).render();
},
singleBook: function(bookID){
console.log(bookID);
new BookView({
el: '#main',
collection: LibraryCollection.get(bookID)
}).render();
}
});
bookID
直接来自我的MongoDB ID并在console.log
内返回但是当我尝试在浏览器中运行时,我收到以下错误:Uncaught TypeError: undefined is not a function
指的是第collection: LibraryCollection.get(bookID)
行
我的LibraryCollection(./library)包含以下内容:
'use strict';
var Backbone = require('backbone');
var Book = require('./book');
module.exports = Backbone.Collection.extend({
model: Book,
url: '/api/library'
});
我的两个GET请求端点都返回以下内容:
/ API /库/
[{"_id":"54a38070bdecad02c72a6ff4","name":"Book Name One"},{"_id":"54a38070bdecad02c72a6ff5","name":"Book Name Two"},{"_id":"54a38070bdecad02c72a6ff6","name":"Book Name Three"},{"_id":"54a38070bdecad02c72a6ff7","name":"Book Name Four"}]
/ API /库/ 54a38070bdecad02c72a6ff4
{"_id":"54a38070bdecad02c72a6ff4","name":"Book Name One"}
编辑否2
我更新了singleBook
的路由器,如下所示:
singleBook: function(id){
var lib = new LibraryCollection;
lib.fetch({
success: function(){
book = lib.get(id);
new BookView({
el: '#main',
model: book
}).render();
}
});
}
答案 0 :(得分:1)
我真的推荐使用codechool骨干课程here作为骨干介绍。
您将拥有一系列模型(待办事项)。每个待办事项都有自己的视图,并显示模型数据,即待办事项描述。你可能想要一个包装器视图,也称为一个集合视图,将每个视图作为一个子视图,但最好在你开始时将其保留。
关于路由器逻辑,尝试将路由器中的功能视为控制器操作(假设您熟悉MVC)。有许多主干扩展可以创建类似MVC控制器的功能。
对于您的问题,当您使用模板引擎渲染链接时,您将在视图中创建链接。想到的一些引擎是Underscore,Handlebars和Mustache。模板可能如下所示:
<a href="/todos/{{ id }}">{{ description }}</a>
在这个模板中,我们传入模型,在花括号之间,您可以看到我们正在尝试提取该模型的ID和描述。 Out模型属性可能如下所示:
{
id: 1,
description: "Go shopping"
}
如果您想获得一个模型,您需要确保模型具有urlRoot属性集。然后你需要像这样获取模型:
var singleTodo = new Todo({id: 1});
singleTodo.fetch();
正如我之前所说的,我真的建议您在深入了解应用之前先观看一些关于主干的好教程。祝你好运!
答案 1 :(得分:0)
我猜你的意思是你想要导航到一个显示单个待办事项的页面?如果是,逻辑将存在于路由器中
var TodosRouter = Backbone.Router.extend({
routes: {
"todo": "allTodos"
"todo/:todoId": "singleTodo"
},
allTodos: function() {
// assume you have a todo listing view named TodoListing, extended from Backbone.View
// which the view inside has the link to click and navigate to #todo/<todoId>
var view = new TodoListing({
el: $('body'),
collection: YourTodosCollection
}).render();
},
singleTodo: function(todoId) {
// assume you have a todo single view named TodoView, extended from Backbone.View
var view = new TodoView({
el: $('body'),
model: YourTodosCollection.get(todoId)
}).render();
}
});
是的,这将有效但它需要从数据库中获取整个集合,然后才能显示单个模型,这可能会耗费大量的网络资源/浏览器内存性能。
在我看来,将书的ID传递给BookView是好的,然后我们从那里获取单本书(前提是我们对ID为param的单本书进行了REST GET调用)。
var BookView = Backbone.View.extend({
render: function () {...},
initialize: function(option) {
this.model.fetch(); // fetch only single book, with the bookId passed below
//alternative - we do not pass the model option at below, we could parse the bookId from the router's since it will be part of param in URL eg: http://xxxx/book/:bookId, then we can do the below
this.model = new BookModel({id: parsedFromRouter});
this.model.fetch();
}
});
new BookView({
el: '#main',
model: new BookModel({id: bookId})
}).render();
fetch调用应该是异步的,所以我们可能想要显示一些加载指示器,只在完成提取时呈现视图
this.model.fetch({
success: function () { //call render }
})