我为类似问题实现了一个解决方案,如下所示。首先,我在 Marionette.View 原型中编写了一个新方法:
Marionette.View.prototype.bubbleMethod = function () {
var args = _.toArray(arguments)
var event = args.shift()
var bubble = event + ':bubble'
this.triggerMethod.apply(this, [ event ].concat(args))
this.triggerMethod.apply(this, [ bubble ].concat(args))
}
这将调用triggerMethod
Marionette 的常规两次:一次使用您的事件名称,因为它打算被处理,第二次使用专门的视图很容易识别,指定用于冒泡事件。
然后,您将需要此类专门的视图和冒泡事件,这些事件旨在被冒泡。您必须注意不要close
代表其他视图调度事件(或任何 Marionette 事件),因为这将导致区域和视图中的各种不可预测的行为。后缀使您可以轻松识别冒泡的:bubble
含义。冒泡视图可能如下所示:
var BubblingLayout = Marionette.Layout.extend({
handleBubbles: function (view) {
var bubble = /:bubble$/
this.listenTo(view, 'all', function () {
var args = _.toArray(arguments)
var event = args.shift()
if (event.match(bubble)) {
event = event.replace(bubble, '')
this.bubbleMethod.apply(this, [ event ].concat(args))
}
}, this)
}
})
您需要确保的最后一件事是能够跨区域冒泡事件(对于具有自定义区域管理器的布局和模块)。show
这可以通过来自区域的事件调度来处理,如下所示:
var BubblingLayout = Marionette.Layout.extend({
regions: {
sidebar: '#sidebar'
},
initialize: function () {
this.sidebar.on('show', this.handleBubbles, this)
},
handleBubbles: function (view) {
var bubble = /:bubble$/
this.listenTo(view, 'all', function () {
var args = _.toArray(arguments)
var event = args.shift()
if (event.match(bubble)) {
event = event.replace(bubble, '')
this.bubbleMethod.apply(this, [ event ].concat(args))
}
}, this)
}
})
最后一部分是让一些东西真正冒出来,这很容易被新bubbleMethod
方法处理:
var MyView = Marionette.ItemView.extend({
events: {
'click': 'clickHandler'
},
clickHandler: function (ev) {
// do some stuff, then bubble something else
this.bubbleMethod('stuff:done')
}
})
var BubblingLayout = Marionette.Layout.extend({
regions: {
sidebar: '#sidebar'
},
initialize: function () {
this.sidebar.on('show', this.handleBubbles, this)
},
onRender: function () {
var view = new MyView()
this.sidebar.show(view)
},
handleBubbles: function (view) {
var bubble = /:bubble$/
this.listenTo(view, 'all', function () {
var args = _.toArray(arguments)
var event = args.shift()
if (event.match(bubble)) {
event = event.replace(bubble, '')
this.bubbleMethod.apply(this, [ event ].concat(args))
}
}, this)
}
})
现在,您可以从代码中任何可以访问BubblingLayout
.