Marionette 将项目添加到 collection 事件触发了两次
Marionette on adding an item to collection event is firing twice
我正在使用 Marionette 2.4,并且有一个 layoutView 正在侦听 childView 中的事件。当事件触发时,我在 collection 中搜索现有模型,如果不存在,我创建一个新模型并将其添加到 collection。如果找到,我会从 collection 中删除该模型。问题是该事件似乎触发了两次。第一次触发时,它会创建模型,但是当它触发两次时,它会在 collection 中找到新创建的模型,然后将其删除。
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' 事件的 child 视图....
var childView = Marionette.ItemView.extend({
events: {
'change input[type="checkbox"]': 'channelSelected'
},
channelSelected: function(args) {
this.triggerMethod('channel:selected', args);
}
});
知道为什么 childView 会两次触发 'channel:selected' 事件吗?
它不是包含正在添加的 collection 的视图,但是当添加 collection 时可能会发生一些事情,它会再次触发事件一些原因。
由于 Marionette 的 "childview* event bubbling",您的函数似乎被触发了两次。来自文档:
When a child view within a collection view triggers an event, that
event will bubble up through the parent collection view with
"childview:" prepended to the event name.
That is, if a child view triggers "do:something", the parent
collection view will then trigger "childview:do:something".
这意味着 "childview:channel:selected"
已经在您的布局视图上被触发(这意味着 onChildviewChannelSelected
函数会在父视图存在时自动执行 http://marionettejs.com/docs/v2.4.7/marionette.functions.html#marionettetriggermethod)。
似乎有几个潜在的解决方法。 1 - 如果您的 handler/function 名称遵循 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/
我正在使用 Marionette 2.4,并且有一个 layoutView 正在侦听 childView 中的事件。当事件触发时,我在 collection 中搜索现有模型,如果不存在,我创建一个新模型并将其添加到 collection。如果找到,我会从 collection 中删除该模型。问题是该事件似乎触发了两次。第一次触发时,它会创建模型,但是当它触发两次时,它会在 collection 中找到新创建的模型,然后将其删除。
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' 事件的 child 视图....
var childView = Marionette.ItemView.extend({
events: {
'change input[type="checkbox"]': 'channelSelected'
},
channelSelected: function(args) {
this.triggerMethod('channel:selected', args);
}
});
知道为什么 childView 会两次触发 'channel:selected' 事件吗?
它不是包含正在添加的 collection 的视图,但是当添加 collection 时可能会发生一些事情,它会再次触发事件一些原因。
由于 Marionette 的 "childview* event bubbling",您的函数似乎被触发了两次。来自文档:
When a child view within a collection view triggers an event, that event will bubble up through the parent collection view with "childview:" prepended to the event name.
That is, if a child view triggers "do:something", the parent collection view will then trigger "childview:do:something".
这意味着 "childview:channel:selected"
已经在您的布局视图上被触发(这意味着 onChildviewChannelSelected
函数会在父视图存在时自动执行 http://marionettejs.com/docs/v2.4.7/marionette.functions.html#marionettetriggermethod)。
似乎有几个潜在的解决方法。 1 - 如果您的 handler/function 名称遵循 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/