2012-08-09 59 views
0

我是Backbone世界的新手,我決定使用Marionette作爲我的第一個嚴肅的項目。Backbone.Marionette:複合視圖在collection.reset()被解僱後消失

有一些困​​難,我設法設置了我的應用程序的基本選項和路由,我對它很滿意,但是現在我面臨着代表Table的CompositeView的阻塞問題。

該視圖呈現在特定佈局的區域內,稱爲「網格」。這個佈局有3個區域:top_controls,table_view和bottom_controls。由於我需要在佈局的某些元素上綁定某些操作,因此我決定將它用作View,並在其中包含「master」集合,以便可以在CompositeView內呈現集合的過濾版本,而不接觸主要的一個。

從我的路由器我把它用這種方式:

App.grid = new Grid({collection: Clt}); 
App.page.show(App.grid); 

佈局的結構是這樣的(我使用requireJS):

var Grid = Backbone.Marionette.Layout.extend({ 

     className: "container-fluid", 

     template: gridLayout, 

     regions: { 
      top_controls: "#top_controls", 
      table_view: "#table_view", 
      bottom_controls: "#bottom_controls", 
     }, 

      initialize: function(){ 

       this.renderTable(this.collection, true);     
      }, 

      renderTable: function(collection, fetch){ 

       if(fetch){ 

        collection.fetch({success:function(){ 

         var vista = new CompView({collection: collection});        
         App.grid.table_view.show(vista); 

        }}); 

       } else { 

        var vista = new CompView({collection: collection});      
        App.grid.table_view.show(vista);      
       } 
      }, 

      events: { 
       "keyup input":"filter_grid" 
      }, 

      filter_grid: function(e){ 

       var $el = e.currentTarget; 
       var to_filter = $($el).val(); 

       if(to_filter==""){ 

        this.renderTable(this.collection, false); 

       } else { 

        var filtered = this.collection.filter(function(item){ 
         return item.get("link_scheda").toLowerCase() == to_filter; 

        }); 

        if(filtered.length>0){ 

         var filtro = new AssocCollection(); 

         filtro.reset(filtered); 

         this.renderTable(filtro, false); 
        } 
       }     
      } 
    }); 

    return Grid; 

佈局模板看起來是這樣的:

<div class="row-fluid" id="top_controls"><input type="text" id="filter" class="input"/></div> 
<div class="row-fluid" id="table_view"></div> 
<div class="row-fluid" id="bottom_controls"><button class='add btn btn-primary'>Add</button></div> 

我CompositeView中的結構類似:

var AssocView = Backbone.Marionette.CompositeView.extend({ 

    tagName: 'table', 
    className: 'table table-bordered table-striped', 
    id: 'tableAssoc', 
    template: assocTemplate, 
    itemView: assocRow, 

    appendHtml: function(collectionView, itemView, index){ 
     collectionView.$("tbody").append(itemView.el); 
    }, 

    events: { 
     "click .sort_link":"sort_for_link", 
    }, 

    sort_for_link: function(){ 

     this.collection.comparator = function(model){ 

      return model.get("link_value"); 
     } 

     this.collection.sort(); 

    }, 

    onRender: function(){ 
     console.log("render table!"); 

    } 

}); 

return AssocView; 

該表的第一個顯示是正確的,也是過濾。 我點擊帶有「sort_link」類的表頭:在集合保持不變的情況下,將整個表從HTML中抹去(我將整個佈局重新渲染)。例如,如果我在另一個地方渲染CompositeView,比如應用程序的主要區域,它都可以按照預期工作。所以我想問題是它位於我的佈局聲明中。

任何幫助將不勝感激!

回答

0

在您的Grid中,您需要覆蓋initialEvents方法,不要執行任何操作。


Grid = Backbone.Marionette.Layout.extend({ 

    initialEvents: function(){}, 

    // ... everything you already have 

}); 

佈局從ItemView擴展而來,而ItemView提供了initialEvents實現。這個方法檢查是否給了一個集合,如果有,它會將集合「重置」事件連接到視圖的「render」方法。在你的情況下,你正在傳遞集合並且不想要這種行爲。所以,重寫initialEvents方法將會糾正它。

更新:我以爲我很久以前就刪除了那個initialEvents。如果你保持最新的w/Marionette版本,抓住v0.9.10(或任何最新的),現在這個問題已經消失。

+0

謝謝!我發現問題是集合的重置事件,但我沒有將它鏈接到佈局視圖。也感謝您的圖書館快速更新! :) – Ingro 2012-08-10 08:58:15