1

我是 Backbone 的初学者,所以这是一个渲染简单模板的非常简单的示例。我在渲染这个模板时遇到了问题。它仅适用于 Chrome。当我在 MasterView 对象中的“this.collection.fetch()”为空但在 Chrome 中有我的集合之后调试此代码时。我不知道为什么它在 Chrome 中有效,但在其他浏览器中无效。

索引.html

    <div class="Presentation">

    </div>

    <script id="slideTemplate" type="text/template">
        <h1><%=slide_title %></h1>
        <h2><%=slide_subheading %></h2>
        <div> <%=content %> </div>
    </script>

模型

define(['backbone','underscore'],function(Backbone,_){
var linkModel = Backbone.Model.extend({
        defaults: {
                    slide_title: "slide", 
        slide_subheading: "sub slide 1",
        content: "bla bla bla"
         }
     });

return linkModel;
    });

收藏

define(['backbone','underscore','models/link','libs/backbone-localstorage'],function(Backbone,_,link,storage){
var linkModels = Backbone.Collection.extend({
    model: link,
    localStorage: new storage('links')

});

return linkModels;
    });

单视图

define(['jquery','backbone','underscore'],function($,Backbone,_){
var linkView = Backbone.View.extend({
    tagName: "article",
    className: "slide-container",
    template: $("#slideTemplate").html(),
    render: function(){
        var tmpl = _.template(this.template);
        this.$el.html(tmpl(this.model.toJSON()));
        return this;
    }
});

return linkView;
    });

主视图

define(['jquery',
    'backbone',
    'underscore',
    'collections/links',
    'views/linkView', 'views/data'], function($, Backbone,_,links,linksView,data){
var favsView = Backbone.View.extend({
    el: $(".Presentation"),
    initialize: function(){
        var self = this;
        this.collection = new links(slides);    
        _.bindAll(this, 'renderLink', 'renderAll');         

              this.collection.fetch();
      this.renderAll();
    },
    renderAll: function(){
        this.collection.each(
            this.renderLink
        );
    },
    renderLink: function(model){
        var view = new linksView({model: model});
        this.$el.append(view.render().el);
        model.save();
    },
    render: function(){
        console.log("Ready...");
    }
});

return new favsView;
  });
4

1 回答 1

1

你在这里有一个简单的“ A in AJAX代表异步”问题:

  this.collection.fetch();
  this.renderAll();

fetch是一个 AJAX 调用,因此无法保证在执行时您的集合中会有任何内容renderAll

推荐的(推荐的)方法是做两件事:

  1. 将视图的方法绑定render到集合的"reset"事件。render当从服务器获取集合时,这将触发调用。
  2. 修改您的render和模板以对空集合执行一些明智的操作。您可以显示Loading...消息,例如No items或其他任何内容。

您的代码应该看起来更像这样:

initialize: function() {
    // Always do this first to be sure that your function
    // references refer to the right things.
    _.bindAll(this, 'render', 'renderLink');

    this.collection = new links(slides);
    this.collection.on('reset', this.render);
    this.collection.fetch();
    this.render(); // If you must.
},
render: function() {
    // And update your template to with a "loading..." message
    // of some sort...
    this.collection.each(this.renderLink);
    return this; // A good convention.
},
renderLink: function(model) {
    var view = new linksView({model: model});
    this.$el.append(view.render().el);
}

render方法用于渲染,不要通过引入一个renderAll可以完成render工作的东西来使事情变得过于复杂。此外,model.save()在您的内部调用renderLink有点奇怪,模型应该已经在服务器上,因为它们刚刚来自fetch并且通常您会将save调用放在一些更新模型以响应用户事件的操作旁边。

于 2012-10-28T17:54:06.630 回答