私はBackboneの世界ではまったく新しいので、Marionetteを使った最初の本格的なプロジェクトに使用することにしました。
いくつかの問題で、アプリの基本的なオプションとルーティングを設定でき、かなり満足していましたが、テーブルを表すCompositeViewでブロッキングの問題が発生しています。
このビューは、「グリッド」と呼ばれる特定のレイアウトの領域内にレンダリングされます。このレイアウトには、top_controls、table_view、bottom_controlsの3つの領域があります。レイアウトのいくつかの要素にアクションをバインドする必要があったので、それをビューとして使用し、その中に「マスター」コレクションを含めることにしました。これにより、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をアプリのメイン領域などの別の場所でレンダリングすると、すべて意図したとおりに機能します。だから私はそれが私のレイアウト宣言の中にあることに問題があると思います。
どんな助けでも大歓迎です!