2

在 Backbone(实际上是 Marionette)中初始化视图后,是否可以更改其集合?我使用带有附加子项的(主)项列表的嵌套模型。该视图显示所有主要项目,并且根据这些项目的当前选择,子项目视图会发生变化。我看到的唯一选择是在选择更改后使用所选主项的子项重新创建子项视图。

这是模型:

model = [
  {
    foo: 'blah',
    bar: [{a: 1, b: 2, c: '3'}, {a: 4, b: 5, c: null}]
  },
  {
    foo: 'abcd',
    bar: [{a: 6, b: 7, c: '8'}, {a: 9, b: 10, c: '11'}]
  }
]

该视图有两个并排的表:

Table1      Table2
------      ------
 blah        a=6, b=7, c='8'
*abcd        a=9, b=10, c='11'

* 表示当前选择的主要项目。我可以在选择后检索 table1 中所选主项的索引,但是如何重新初始化 table2 中的视图?

编辑:这里有一些代码用于进一步说明:

var MainCollectionViewRow = Backbone.Marionette.ItemView.extend({
    template: _.template(...),
    tagName: 'tr'
});

var MainCollectionView = Backbone.Marionette.CompositeView.extend({
    tagName: 'table',
    template: _.template(...),
    itemView: MainCollectionViewRow,
    events: {
        'click tbody tr': 'selectItem',
    },
    appendHtml: function(collectionView, itemView, index) {
        $(itemView.el).data('index', index);
        collectionView.$('tbody').append(itemView.el);
    },
    selectItem: function(e) {
        var index = $(e.currentTarget).data('index');
        var newMainItem = this.collection.at(index);
        // This doesn't work...
        subView.initialize({'collection': newMainItem.get('bar')});
    }
});

var Bar = Backbone.Model.extend({
    defaults: {
        a: null,
        b: 0,
        c: 'text',
    }
});

var BarCollection = Backbone.Collection.extend({
    model: Bar
});

var Main = Backbone.Model.extend({ 
    defaults: {
        foo: null, 
        bar: BarCollection,
    },
    initialize: function() {
        var bar = new BarCollection(this.get('bar'));
        this.set('bar', bar);
    }
});

var MainCollection = Backbone.Collection.extend({
    model: Main,
    url: '/some/url/'
});

app.someRoute = function() {
    var region = new MainRegion();
    var layout = new MainLayout();
    region.show(layout);

    new MainCollection().fetch({
        success:function (list) {
            mainView = new MainCollectionView({
                collection: list
            });
            var subItem = list.first();
            subView = new SubCollectionView({
                collection: list.get('bar')
            });

            layout.main.show(mainView);
            layout.sub.show(subView);
        }
    });
}

app.route('some/route', 'someRoute');
4

1 回答 1

1

我推荐使用 Marionette 的控制器。它需要更多代码,但随着您的应用程序的增长,您将能够保持您的集合和视图逻辑干净。您还将获得可添加书签的链接以及使用后退和前进浏览器操作。

var Router = Marionette.AppRouter.extend({
    appRoutes: {
        "": "navigate",
        "section/:index": "navigate"
    },
});

var Controller = Marionette.Controller.extend({

    initialize: function(options){
        this.region = new MainRegion();
        this.layout = new MainLayout();

        this.mainCollection = new MainCollection();
        this.subCollection = new Backbone.Collection();

        this.mainView = new MainCollectionView({
            collection: this.mainCollection
        });
        this.subView = new SubCollectionView({
            collection: this.subCollection
        });
    },
    navigate: function(index){
        index = index || 1;
        var subList = this.mainCollection.at(index);
        this.subView.collection.reset(subList);
    },
    start: function(){
        var self = this;
        var p = this.mainCollection.fetch();

        p.done(function(){
            self.showRegion();
            self.showLayout();
        })
    },
    showRegion: function() {
        this.region.show(this.layout);
    },
    showLayout: function() {
        this.layout.main.show(this.mainView);
        this.layout.sub.show(this.subView);
    }

});

Mod.addInitializer(function(){
    Mod.controller = new Controller();
    Mod.router = new Router({
        controller: Mod.controller
    });
    Mod.controller.start();
});

MainCollectionView:我们现在可以依靠路由来处理这个问题,更新您的视图以使用链接。

//selectItem: function(e) {
  //var index = $(e.currentTarget).data('index');
  //var newMainItem = this.collection.at(index);
  // reset the collection http://backbonejs.org/#Collection-reset
  //subView.collection.reset(newMainItem.get('bar'));
//}

子集合视图:

initialize: function() {
  _.bindAll(this);
  this.collection.on("reset", this.render, this);
}
于 2013-04-29T14:29:56.407 回答