backbone.js视图没有't由于异步获取而显示结果;t渲染

backbone.js view doesn't display results because of asynchronous fetch , doesn't render

本文关键字:异步 获取 渲染 结果 显示 视图 js backbone 于异步      更新时间:2024-01-08

我注意到我的视图的渲染函数被调用了两次。这是我的代码:

视图,这是一个集合:

define([
  'jquery',
  'underscore',
  'backbone',
  'mustache',
  'icanhaz',
  'views/spots/Spot',
  'collections/Spots',
  'text!../../../../templates/spots/spots.mustache!strip',
], function($,
            _,
            Backbone,
            mustache,
            ich,
            SpotView,
            Spots,
            SpotsTemplate){
  var SpotsView = Backbone.View.extend({
    initialize: function(){
       var ich = window['ich'],
          spots = ich.addTemplate('spots',SpotsTemplate);
          spots = ich['spots'];
          this.template = spots;
      _.bindAll(this,'render'); 
      var self = this;
      this.collection.bind("all", function() { self.render(); }, this);
      this.collection.fetch(); 
    },
    events: {
        "change": "render"
    },
    render: function(){
      window.counter = window.counter +1;
      console.log('inside render for the ' + window.counter + ' times!');
      this.el = this.template();
      this.collection.each(function (spot) {
        $(this.el).append(new SpotView({model:spot}).render().el);
      }, this);
      console.log($(this.el).children().length);
      return this;
    }
  });
  // Returning instantiated views can be quite useful for having "state"
  return SpotsView;
});

当我尝试显示时,app.js中的代码

   var  spots = new Spots({model: Spot});
    window.counter = 0 + 0;
    var spots_view = new SpotsView({collection: spots});
    $('#spots').html(spots_view.render().el);

我的输出是:

inside render for the 1 times! 
1 
inside render for the 2 times! 
6 

在玩不同的东西时,我注意到它甚至被调用了3次。我做错了什么?很明显,当结果从服务器被带到渲染函数时,这一行:

$('#spots').html(spots_view.render().el);

已经通过

非常感谢

视图的initialize显示:

this.collection.bind("all", function() { self.render(); }, this);
this.collection.fetch();

CCD_ 2将重置集合:

当模型数据从服务器返回时,集合将重置。

重置集合将:

[触发]结束时的单个"重置"事件

通过绑定到"all",集合上的任何事件都将触发render调用。因此,当您显式地说spots_view.render()时,您的视图将渲染一次,当fetch调用从服务器返回内容时,视图将再次渲染。

顺便说一句,你有这个:

_.bindAll(this,'render');

因此,您不需要使用selfself.render(),也不需要向bind提供上下文参数,您可以简单地说:

_.bindAll(this, 'render');
this.collection.bind("all", this.render);

您也在render:中执行此操作

this.el = this.template();

这从来都不是个好主意。如果您需要更改视图的this.el,则应该使用setElement;其将负责重新绑定事件并更新CCD_ 13。但是,如果您已经将this.el放入DOM中,那么这对您没有帮助。与其完全替换el,不如将所需的一切放入this.el:

var $content = $(this.template());
this.collection.each(function (spot) {
    var spot = new SpotView({ model: spot });
    $content.append(spot.render().el);
});
this.$el.html($content);

然后,您可以清空它并重新渲染它以响应事件,而不会出现任何问题。