Backbone.Marionette:在触发collection.reset()之后,CompositeView消失了

时间:2012-08-09 15:33:01

标签: backbone.js marionette

我在Backbone的世界里相当新,我决定用Marionette作为我的第一个认真的项目。

由于遇到一些困难,我设法设置了我的应用程序的基本选项和路由,我对它非常满意,但现在我遇到了一个代表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,比如app主区域,它就会按预期工作。所以我想问题是它位于我的布局声明中。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

Grid中,您需要覆盖initialEvents方法,不要在其中执行任何操作。


Grid = Backbone.Marionette.Layout.extend({

  initialEvents: function(){},

  // ... everything you already have

});

布局从ItemView扩展,ItemView提供initialEvents实现。此方法检查是否为其提供了集合,如果是,则将集合“reset”事件连接到视图的“render”方法。在您的情况下,您正在传递集合,并且不希望出现此行为。因此,覆盖initialEvents方法将纠正它。

更新:我以为我很久以前就删除了initialEvents。如果你保持与Marionette版本的最新版本,请抓住v0.9.10(或者最新的版本),现在这个问题就消失了。