Backbone.js单个集合项视图

时间:2014-12-30 16:32:54

标签: javascript backbone.js views

我最近开始构建我的第一个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();
  }
});

}

2 个答案:

答案 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();
  }
});

基于编辑2更新

是的,这将有效但它需要从数据库中获取整个集合,然后才能显示单个模型,这可能会耗费大量的网络资源/浏览器内存性能。

在我看来,将书的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 }
})