【问题标题】:Marionette on adding an item to collection event is firing twice将物品添加到收藏事件的木偶触发了两次
【发布时间】:2016-06-02 11:49:01
【问题描述】:

我正在使用 Marionette 2.4 并且有一个 layoutView 正在监听 childView 中的事件。当事件触发时,我在集合中搜索现有模型,如果不存在,我创建一个新模型并将其添加到集合中。如果找到它,我会从集合中删除该模型。问题是该事件似乎被触发了两次。第一次触发时,它会创建模型,但是当它触发两次时,它会在集合中找到新创建的模型,然后将其删除。

var layout = Marionette.LayoutView.extend({
  childEvents: {
    'channel:selected': 'onChildviewChannelSelected'
  },
  onChildviewChannelSelected: function (childView, args) {
    var linkCollection = this.getRegion('regionWithCollectionView').currentView.collection;
    var modelToUpdate = linkCollection.where({channel: args.currentTarget.value});
    if(modelToUpdate) {
      this.removeModel(linkCollection, modelToUpdate);
    } else {
      this.addModel(linkCollection, args.currentTarget.value);
    }
  },
  removeModel: function (collection, model) {
    collection.remove(model);
  },
  addModel: function (collection, channel) {
    var newEntity = new MyApp.Entities.Link();
    newEntity.set('channel', channel);
    collection.add(newEntity);
  }
});

这里是触发 'channel:selected' 事件的子视图......

var childView = Marionette.ItemView.extend({
    events: {
      'change input[type="checkbox"]': 'channelSelected'
    },
    channelSelected: function(args) {
       this.triggerMethod('channel:selected', args);
    }
});

知道为什么 childView 会触发 'channel:selected' 事件两次吗?

保存要添加到的集合的不是视图,但是当将集合添加到其中时可能会发生一些事情,它会由于某种原因再次触发事件。

【问题讨论】:

    标签: backbone.js collections marionette


    【解决方案1】:

    由于 Marionette 的“childview* 事件冒泡”,您的函数似乎被触发了两次。来自文档:

    当集合视图中的子视图触发事件时, 事件将通过父集合视图冒泡 "childview:" 附加在事件名称之前。

    也就是说,如果子视图触发“do:something”,父视图 然后集合视图将触发“childview:do:something”。

    这意味着 "childview:channel:selected" 已经在你的 layoutview 上被触发(这意味着如果 http://marionettejs.com/docs/v2.4.7/marionette.functions.html#marionettetriggermethod 存在父视图,onChildviewChannelSelected 函数会自动在父视图上执行)。

    似乎有几个潜在的解决方法。 1 - 如果您的处理程序/函数名称遵循 Marionette 约定,请不要指定 childEvents 处理程序。

    var LayoutView = Marionette.LayoutView.extend({
      template: false,
      el: '.container',
      regions: {
        'regionWithCollectionView': '.collection-view-container'
      },
      onChildviewChannelSelected: function (childView, args) {
        console.log("layoutview::channelSelected - child " + childView.model.get('channel') + " selected");
      }
    });
    

    小提琴显示解决方法 #1:https://jsfiddle.net/kjftf919/

    2 - 将 LayoutView 的子视图函数处理程序重命名为与 Marionette 的自动事件冒泡不冲突的名称。

    var LayoutView = Marionette.LayoutView.extend({
      template: false,
      el: '.container',
      regions: {
        'regionWithCollectionView': '.collection-view-container'
      },
      childEvents: {
        'channel:selected':'channelSelected'
      },
      channelSelected: function (childView, args) {
        console.log("layoutview::channelSelected - child " + childView.model.get('channel') + " selected");
      }
    });
    

    小提琴显示解决方法 #2:https://jsfiddle.net/kac0rw6j/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 2014-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多