2013-08-24 68 views
1

我发现了一些Backbone.js代码的示例,然后我采用了这些代码以满足我的需要。在获取内容之前调用Backbone.js渲染器

在获取任何内容之前调用CommentListViewrender功能。看起来,当有内容要呈现时,它不会再次调用。

后端返回两个结果,所以这不是问题。

// Models 
window.Comment = Backbone.Model.extend(); 

window.CommentCollection = Backbone.Collection.extend({ 
    model:Comment, 
    url:"/api/comments/cosmopolitan" 
}); 


// Views 
window.CommentListView = Backbone.View.extend({ 

    tagName:'ul', 

    initialize:function() { 
     this.model.bind("reset", this.render, this); 
    }, 

    render:function (eventName) { 
     console.log(this.model.models); 
     _.each(this.model.models, function (comment) { 
      console.log(comment); 
      $(this.el).append(new CommentListItemView({model:comment}).render().el); 
     }, this); 
     return this; 
    } 

}); 

window.CommentListItemView = Backbone.View.extend({ 

    tagName:"li", 

    template:_.template($('#tpl-comment-list-item').html()), 

    render:function (eventName) { 
     $(this.el).html(this.template(this.model.toJSON())); 
     return this; 
    } 

}); 

// Router 
var AppRouter = Backbone.Router.extend({ 

    routes:{ 
     "":"list" 
    }, 

    list:function() { 
     this.commentList = new CommentCollection(); 
     this.commentListView = new CommentListView({model:this.commentList}); 
     this.commentList.fetch(); 

     $('#sidebar').html(this.commentListView.render().el); 
    } 
}); 

var app = new AppRouter(); 
Backbone.history.start(); 
+0

骨干版本1.0.0 – phidah

回答

4

fetch的行为在Backbone 1.0.0中有所变化。从ChangeLog

  • 更名为集合的 “更新” 到设置,并行度与同类model.set(),和对比度复位。这是取回后的默认更新机制。如果您想继续使用“重置”,请通过{reset: true}

而且Collection#fetch说:

collection.fetch([options])

取模型的默认设置为这个集合从服务器,上采集设置他们,当他们到达。 [...]当从服务器模型数据的回报,它采用设置到(智能)合并获取的车型,除非你通过{reset: true}

initialize只是结合"reset"

this.model.bind("reset", this.render, this); 

您可以绑定到"add""remove""change"事件Collection#set将产生或者你可以明确要求"reset"事件,当你fetch

this.commentList.fetch({ reset: true }); 

几个其他的事情,而我在这里:

  1. 由于您的CommentListView视图是使用一个集合,而不是一个模式,你可能会想将它命名collection

    this.commentListView = new CommentListView({collection: this.commentList}); 
    

    然后参考this.collection里面的视图。有关视图构造函数如何处理其参数的详细信息,请参阅View#initialize

  2. 收藏有各种Underscore methods mixed in所以你可以说this.collection.each(function(model) { ... })而不是_.each(this.model.models, ...)
  3. 视图维护jQuery包装的el的缓存版本$el因此您可以说this.$el而不是$(this.el)
  4. 请注意诸如console.log(this.model.models)之类的内容。控制台通常会抓取一个实时参考,因此当您看起来,而不是调用console.log时,控制台中显示的内容将为this.model.models的状态。在面对计时和AJAX问题时使用console.log(this.model.toJSON())更可靠。
  5. 您可能希望切换到listenTo而不是bind(AKA on),因为它不易受内存泄漏的影响。
+0

非常感谢 - 解决方案(绑定添加,删除和更改工作)以及提供一般建议。 – phidah

0

通常用于为fetch创建侦听器,当fetch完成并更改模型或集合时会有回调。试试这个:

var AppRouter = Backbone.Router.extend({ 

    routes:{ 
     "":"list" 
    }, 

    list:function() { 
     this.commentList = new CommentCollection(); 
     this.commentListView = new CommentListView({model:this.commentList}); 
     this.listenTo(this.commentList,'change', this.makeRender); 
     this.commentList.fetch(); 


    }, 
    makeRender: function(){ 
     $('#sidebar').html(this.commentListView.render().el); 
    } 

}); 
+0

我修改了代码,并增加了一些的console.log stagements调试(代码:http://pastebin.com/eQn2uUE6) - 输出:CommentListView:初始化 - AppRouter:列表完成 - 即使AJAX请求成功完成,也不会调用makeRender。 – phidah