Backbone.js集合不添加对象

问题描述:

我想从服务器获取集合数据并将其加载到我的集合对象中,并使用Backbone.js。我想在开始时获取这些数据,并使用这些数据加载我的html页面。但是,我从服务器下载的数据没有正确填充到集合中。收集长度为零,有谁知道我做错了什么?Backbone.js集合不添加对象

(function ($) { 
    window.Menu = Backbone.Model.extend({}); 

    window.MenuCollection = Backbone.Collection.extend({ 
     model: window.Menu, 
     initialize: function() { 
      _.bindAll(this, 'parse'); 
     }, 
     url: function(){ 
      return 'http://localhost:8080/testing/123'; 
     }, 
     parse : function(resp) { 
      console.log(resp); 
      // this prints: 
      // "[{"name":"helloworld1"},{"name":"helloworld2"}]" 

      this.add(resp); 
      this.add(new Menu({name:"black perl"})); 
      console.log(this); 
      // the length of the object in the console log is 0 
     } 
    }); 

    window.MenuView = Backbone.View.extend({ 
     tagName: 'li', 
     initialize: function() { 
      _.bindAll(this, 'render'); 
     }, 
     render: function() { 
      $(this.el).html('<span>'+this.model.get('name')+'</span>'); 
      return this; 
     } 
    }); 

    window.MenuListView = Backbone.View.extend({ 
     tagName: 'ul', 
     initialize: function() { 
      _.bindAll(this, 'render'); 
     }, 
     render: function() { 
      this.model.each(function(menu) { 
       $(this.el).append(new MenuView({model:menu}).render().el); 
      }); 

      return this; 
     } 
    }); 

    var view; 
    AppView = Backbone.View.extend({ 
     el: $("body"), 
     initialize: function() { 
      this.menus = new MenuCollection(); 
      this.menuListView = new MenuListView({model:this.menus}); 
      view = this.menuListView; 
      this.menus.fetch({success: function(){console.log("success"); 
      console.log(view.render().el);}}); 
     }, 
     events: { 

     } 
    }); 

    var appview = new AppView; 

})(jQuery); 
+0

我在这里看不到很多努力来简化示例代码。如果您可以向我们展示重现相同问题的非常小版本的代码,可能会有所帮助。 – fguillen 2012-03-13 15:37:49

你误解如何parse作品:

解析collection.parse(response)

解析无论何时,只要一个集合的模型是由服务器返回骨干调用,取。该函数传递了原始response对象,并应返回要添加到集合中的模型属性数组。

因此,如果您从服务器获得[{"name":"helloworld1"},{"name":"helloworld2"}],则甚至不需要parse实现。

你看到的add的奇怪行为更有趣。如果我们看一下fetch,我们看到:

fetch: function(options) { 
    //... 
    options.success = function(resp, status, xhr) { 
    collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options); 
    if (success) success(collection, resp); 
    }; 
    //... 
} 

你调用fetch没有add选项设置这样的事情发生是这样的:

  1. collection.parse被调用。
  2. 您的parse增加了一些东西,并调用console.log
  3. 你的解析不会返回任何东西。
  4. collection.reset被调用以添加parse返回的内容。
  5. reset将清除该集合,然后添加任何内容,因为parse没有返回任何内容。

一些console.log实现把一个活引用在控制台,这就是为什么你在控制台得到一个空的集合:console.log(this)最终显示的reset电话后this

+0

该代码似乎已经改变,因为这个答案写道:https://github.com/jashkenas/backbone/blob/master/backbone.js#L873我们现在应该做什么? – qwertynl 2014-07-03 14:21:20

+0

@qwertynl关于'add'的一点只是对他们从'parse'看到的看似奇怪的行为的解释。答案的肉是根本不需要“解析”实现。 – 2014-07-03 18:34:07

实际上,您遇到的另一个问题是您没有将“this”传递到您的视图渲染中for循环的上下文中。因此,当你返回“el”元素时,你的html页面将是空白的,没有来自服务器的内容。

+0

而'MenuListView'应该使用'collection'而不是'model'。 – 2012-03-12 23:11:14

请记住,来自backbone.js 0.9+ 版本0.5.3的解析方法不会调用解析。