Backbone:即使获取了集合,也不会在View中呈现集合

时间:2014-03-26 13:08:27

标签: javascript html json backbone.js model-view-controller

我知道关于此问题有几个问题,但我的答案对我来说并不是很清楚。这就是为什么我再次提出这个问题所以我可以得到一个清晰简单的答案。

我在Backbone中总是遇到Collection问题,特别是用JSON数据填充它。

我似乎无法在View中渲染集合,即使在firebug中我可以看到它,它正从服务器获取,但屏幕仍然是空的。 此外,当我执行console.log('callers: ', this.callerList)时,它会返回一个models=[0]的对象。但是当我展开对象时,models充满了来自JSON文件的数据。 Backbone发生了什么,结果令人困惑?

有人可以向我解释怎么做吗?我一直在与这种斗争多年,我无法理解它。

非常感谢

JS:

(function($, window) {

  // model
  var CallerModel = Backbone.Model.extend({});

  // collection
  var CallersList = Backbone.Collection.extend({
      model: CallerModel,
      url: 'js/json/callers.json'
  });

  // view
  var CallerView = Backbone.View.extend({
      el: '.caller-app',

      template: _.template($('#callers-template').html()),

      initialize: function() {
          this.callerList = new CallersList();
          this.callerList.fetch();
          this.callerList.bind('reset', this.render);

          console.log('caller: ', this.callerList);
      },

      render: function(e) {

                  console.log('RENDER');

          _.each(this.collection.models, function(caller) {
              this.$el.append(this.template(caller.toJSON()));
                          console.log('callerList: ', caller);
          }, this);

          return this;
      }
  });

  // start
  var callerView = new CallerView();

}(jQuery, window));

HTML:

<!-- wrapper -->
<div class="wrapper">
    <h1>Missed Calls App</h1>

    <div class="caller-app"></div>

</div>
<!-- wrapper -->


<!-- templates -->
<script type="text/template" id="callers-template">
    <div class="caller">
        <h2><%= title %> <%= name %> called</h2>
        <h3>From <%= agency %></h3>
        <p>When: <%= when %></p>
        <p>Contact: <%= tel %></p>
        <p>Says:"<%= message %>"</p>
    </div>
</script>
<!-- templates -->

JSON:

[
  {
      "id": 1,
      "title": "Mrs",
      "name": "Mui",
      "agency": "Ryuzanpaku Dojo",
      "when": "evening",
      "tel": "0207 123 45 67",
      "message": "Check your availability"
  },
  {
      "id": 2,
      "title": "Mrs",
      "name": "Shigure",
      "agency": "Ryuzanpaku Dojo",
      "when": "evening",
      "tel": "0207 123 45 67",
      "message": "Check your availability"
  }
]

1 个答案:

答案 0 :(得分:2)

您还没有动手为 CallerView 分配一个集合,此外,当您迭代该集合时,您应该使用this.collection.models而不是this.model.models

例如,在初始化您的来电者列表时         initialize:function(){

    initialize: function() {
    this.collection = new CallersList();
    this.collection.fetch();
    this.collection.bind('reset', this.render);
   }

渲染时

render: function(e) {

          _.each(this.collection.models, function(caller) {
              this.$el.append(this.template(caller.toJSON()));

          }, this);

          return this;
      }

这是指向jsbin

的链接

其他一些要点

通常,您希望尽可能地解耦代码。为此,最好在视图之外声明和初始化您的集合,然后将其传入。这也有利于使您的代码更具可重用性,例如说您想要呈现第二个调用列表(比如说)最近的调用),您现在可以创建一个传递集合和元素的视图的第二个实例。

例如

var missedCalls = new CallersList();
var callerView = new CallerView({collection : missedCalls, el: '#missedCalls' });
missedCalls.fetch();


var recentCalls = new CallerList(); //you probably want to use a different url
var recentCallersView = new CallerView({collection : recentCalls, el:'#recentCalls'}); 
recentCalls.fetch();

值得一提的另一点是,目前您要为每次获取呈现集合中的所有项目,包括已经呈现的任何项目。您可能希望在呈现之前清空el,或者转而聆听add事件,并在添加时单独呈现每个项目。此外,值得注意的是,fetch

并非真正意味着用于在页面加载时加载数据documentation

  

请注意,不应使用fetch来填充页面上的集合   load - 加载时所需的所有模型都应该已经被引导   在地方。 fetch用于延迟加载模型   不需要立即的接口:例如,文档   可以切换打开和关闭的笔记集合。