将项目添加到集合事件的Marionette已触发两次



我使用的是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"事件吗?

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

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

当集合视图中的子视图触发事件时事件将在父集合视图中弹出事件名称前加了"childview:"。

也就是说,如果子视图触发了"do:tsomething",则父视图集合视图将触发"childview:do:tsomething"。

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

似乎有几个潜在的解决办法。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");
}
});

Fiddle显示解决方法#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");
}
});

Fiddle显示解决方法#2:https://jsfiddle.net/kac0rw6j/

最新更新