16

私は本当に基本的なものだと思っていますが、バックボーン:1つのコレクションのイベントに複数のビューを登録していますか?これは悪い習慣ですか?

私はコレクションビューと1つのビューが更新されるコレクションに依存している例を見てきました。コレクションイベントを購読しようとしている複数のビュー(リセット、addOne、addAllなど)がある場合はどうなりますか?

これについて何かしていない/していませんか?これの例はありますか?それは理にかなっていますか?

すべての情報はMUCHあなたがやっている

var Coll = Backbone.Collection.extend({ 
     model: SingleModel, 
     url: 'service', 
     initialize: function(){ 
      console.log('collection inited') 

     }   

    }); 

    var SingleModel = Backbone.Collection.extend({});    

    var CollView = Backbone.View.extend({     
     el: 'ul', 
     template: Handlebars.compile(someContainerTemplate), 
     init: function(){ 
      _.bindAll(this, 'render', 'addAll', 'addOne'); 
      this.collection.bind("reset", this.addAll); 

      this.collection.fetch(); 
     }, 
     render: function(){ 
      $(this.el).append(this.template()) 
     }, 

     addAll: function(){ 
      this.collection.each(this.addOne); 
     }, 

     addOne: function(model){ 
      var view = new SingleView({ model: model })    
     } 
    }) 

    var SingleView = Backbone.View.extend({ 
     tagName: "li", 
     events: { 
      "click .delete": "remove"      
     }, 
     template: Handlebars.compile(someTemplateForSingleItem), 
     initialize: function() { 
     _.bindAll(this,'render'); 

      this.model.bind('save', this.addOne); 
      this.model.bind('destroy', removeEl); 
     }, 

     remove: function(){ 
      this.model.destroy(); 
     }, 

     removeEl: function(){ 
      $(this.el).remove(); 
     }, 

     render: function() { 
      var context = this.model.toJSON(); 
      return $(this.el).append(this.template(context)); 
     },  
    }) 


    // standard so far (excluding any bad practices), 
    // but what if you have another view dependent on 
    // say the number of length of the collection, and 
    // you want it to update if any single models are destroyed 

    var HeaderView = Backbone.View.extend({ 
     tagName: "div#header", 
     template: Handlebars.compile(someHeaderTemplate), 
     initialize: function() { 
     _.bindAll(this,'render'); 

     this.model.bind('save', this.addOne); 
     }, 

     render: function() { 
      //assigning this collection length 

      var context = this.collection.length; 
      return $(this.el).append(this.template(context)); 
     },  
    });   

    var coll = new Coll(); 
    new CollView({ collection: coll }); 
    new HeaderView({ collection: coll}); 

答えて

30

どう評価されて完全に罰金やバックボーンを使用する理由の一部です。 Backbone introductionから:

UIアクションを変更するには、モデルの属性を起こすたびに、モデルは「変更」イベントをトリガし、

モデルの状態を表示するすべてのビューには、ビューが表示されず、「ビュー」ではなく「すべてのビュー」と表示されます。

1つのコレクションの複数のビューの1つの例はチャットシステムです。あなたがオンラインのユーザーの集まりを持っているとします。そして、あなたは1つのOnlineUsersインスタンスが、両方を持っていると思います

var User = Backbone.Model.extend({}); 
var OnlineUsers = Backbone.Collection.extend({ 
    model: User 
}); 

var CounterView = Backbone.View.extend({ 
    tagName: 'span', 
    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.collection.on('add', this.render); 
     // other interesting events... 
    }, 
    render: function() { 
     this.$el.text(this.collection.size()); 
     return this; 
    } 
}); 
var ListView = Backbone.View.extend({ 
    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.collection.on('add', this.render); 
     // other interesting events... 
    }, 
    render: function() { 
     var html = this.collection.map(function(m) { 
      return '<p>' + m.get('name') + '</p>'; 
     }); 
     this.$el.html(html.join('')); 
     return this; 
    } 
}); 

:あなたは、ユーザーが表示されていることをオンラインで人々の数と(同じコレクションの)別のビューを表示し、ヘッダー内の1つの単純なビューを持っているかもしれませんCounterViewListViewのインスタンスがそれを見ています。ユーザーがオンラインになるかオフラインになると、両方のビューが必要に応じて更新されます。

簡単なデモ:http://jsfiddle.net/ambiguous/eX7gZ/

は、上記の例のような状況は、あなたがやっているものの正確並べ替えのように聞こえる、バックボーンの元となったものの正確なものです。よくやった。

+1

おかげで、理にかなっています! –

2

同じ問題がありました。複数のホルダービューを使用することなく、モデルごとに固有の内部イベントを持つ複数のjQueryテンプレートを使用する必要がありました。これは、私たちが思いついたのソリューションです:

var myHolderView = Backbone.View.extend({ 
    el: '#views', 
    render: function(){ 
     // This is because 'this' change inside the collection.each 
     var $this = this; 

     // If you want a wrapper template 
     var wrapperHtml = $('#view-wrapper-template').tmpl(); 
     $this.$el.append(wrapperHtml); 
     $wrapper = $this.$el.find('> div'); // If wrapper is a div 


     $this.collection.each(function(model){ 
      // Render and append the viewA with internal events 
      var viewA = new myViewA({model: model}); 
      viewA.render(); 

      // Use this to add the views content (viewA.el) to this views element ('#views') 
      //$this.$el.append(viewA.el); 

      // Use this to add the view content (viewA.el) to this views wrapper element ($wrapper) 
      $wrapper.append(viewA.el); 


      // Render and append the viewB with internal events 
      var viewB = new myViewB({model: model}); 
      viewB.render(); 
      //$this.$el.append(viewB.el); 
      $wrapper.append(viewB.el); 


      // Add more views here... 
     }); 
    } 
}); 

完全なソースや作業例:答えを http://jsfiddle.net/HLv5z/9/

関連する問題