0

ビューのレンダリング関数が 2 回呼び出されていることに気付きました。これが私のコードです:

コレクションを取得するビュー:

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

すでに過ぎた

どうもありがとう

4

1 に答える 1

2

あなたの見解initializeはこう言っています:

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

コレクションをfetchリセットします。

モデル データがサーバーから返されると、コレクションはリセットされます。

コレクションをリセットすると:

[トリガー] 最後に単一の「リセット」イベント

にバインドすることにより"all"、コレクションのすべてのイベントがrender呼び出しをトリガーします。したがって、明示的に言うとビューが1回レンダリングされ、呼び出しがサーバーから何かを取得spots_view.render()したときに再度レンダリングされます。fetch

余談ですが、これがあります:

_.bindAll(this,'render');

したがって、コンテキスト引数を使用selfしたり、 に指定したりする必要はありません。単純に次のように言えます。self.render()bind

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

あなたもあなたの中でこれをやっていますrender

this.el = this.template();

それは決して良い考えではありません。ビューの;setElementを変更する必要がある場合は、使用する必要があります。this.elこれにより、イベントの再バインドと更新が処理されthis.$elます。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);

次に、それを空にして、イベントに応じて問題なく再レンダリングできます。

于 2012-07-23T20:53:10.053 に答える