首页 > Backbone里两个view(或者说collection)怎么交互?

Backbone里两个view(或者说collection)怎么交互?

我有viewA、viewB,分别对应collectionA、collectionB(他们model类型相同)
目标:点击viewA中一个元素时,将这个元素对应的model添加到collectionB,viewB同上所述
我该怎么做?

var ViewA = Backbone.ViewA.extend({
  el: $('xxx'),
  .....
  events: {
   "click": "trans"
  },
  trans: function(event) {
    var index = event.target.dataset.n;//通过data、元素index之类乱七八糟的获取序列号,总之不重要
    //我疑惑的是下面的
    var model = this.collection.at(index);
    collectionB.add(model) //这样也太傻了吧
  }
});
var viewA = new ViewA({collection: collectionA})

感觉别别扭扭,依赖乱七八糟的


我觉得这完全看复用,如果viewA viewB都不会在别的地方复用,那怎么耦合都无所谓,没必要故意拆

如果其中某一个view会被复用,那么想想怎么被复用就知道怎么解耦了

顺便说一下以我揣测的这个系统的其余部分,我的做法可能是把A和B抽一个共同部分ListView出来,列表视图能够输出列表项被点击的事件,然后为题主这个情形写个新的叫ABListView之类的玩意儿

    #new ABListView({A: CollectionA, B: CollectionB})

    ABListView = View.extend
        initialize: (option)->
            this.children = [option.A, option.B].map (collection, k)->
                child = new ListView {collection: collection}
                child.on 'itemClick', this.childItemClick
                child

        childItemClick: (event)->
            #假设event已经有我们要的"本次点击对应view"和“本次点击对应model”
            #1-k 就是 1<==>0 互换
            this.children[1 - this.children.indexOf event.view].collection.add event.model


var ViewA = Backbone.View.extend({
  el: $('xxx'),
  events: {
   "click": "trans"
  },
  trans: function(event) {
    var index = event.target.dataset.n;
    var model = this.collection.at(index);
    this.trigger('trans', model)
  }
});

var ViewB = Backbone.View.extend({
  receive: function (model) {
    this.collection.add(model)
  }
});

var viewA = new ViewA({collection: collectionA})
var viewB = new ViewB({collection: collectionB})

// 这样
viewA.on('trans', function (model) {
  viewB.receive(model)
})

// 或者
viewB.listenTo(viewA, 'trans', function (model) {
  this.receive(model)
})

如果没有弄懂Backbone,不建议碰Marionette,因为用不好它。


楼主的代码,我觉得写的没问题。不知楼主究竟是哪里不满意,想写成什么样子?


楼主的意思比较清楚,而且感觉是对的,乱乱的,其实是因为这样写会太耦合,ViewA不应该包含ViewB

而最好通过事件进行交互。

如:

var eventAcrossView = _.extend({}, Backbone.Events);

// view one needs to trigger an event in view2
ViewA = Backbone.View.extend({

    trans: function(event) {
        eventAcrossView.trigger('viewAClicked', { 'some' : 'data' } );
    })
})

ViewB = Backbone.View.extend({
    initialize: function() {
        eventAcrossView.on('viewAClicked', this.onViewAClicked, this);
    },
    onViewAClicked : function() {
        // update model
    }
})

View 是用来做什么的?它是用来 render 内容的,所以对数据本身的操作详细过程怎么可以封装到 View 里面?你可以在 View 里面对 Model 进行操作,但是操作本身请定义在 Model 或者 Collection 内。
此外,Backbone 直写复杂页面交互逻辑时确实不太好组织代码,所以我推荐你使用 Marionette + Backbone,像现在这种情况的话,在 Marionette 内可以使用 CollectionView 来处理 Collection,而使用 ItemView 来处理单个 Model 的情形。

【热门文章】
【热门文章】