骨干渲染视图,但仅限Chrome

时间:2012-10-28 14:11:11

标签: ajax backbone.js requirejs fetch

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

的index.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;
    });

SingleView

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;
  });

1 个答案:

答案 0 :(得分:1)

您在 AJAX 中有一个简单的“ A 代表异步”问题:

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

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

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

  1. 将您的观点的render方法绑定到集合的"reset"事件。当从服务器获取集合时,这将触发render调用。
  2. 修改您的render和模板以使用空集合做一些合理的事情。您可以显示正在加载... 消息,例如 No items 或其他任何内容。
  3. 您的代码应该更像这样:

    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调用一些更新模型以响应用户事件的操作。