因此,尽管在 Twitter 上与@julio_menedez 和@marionettejs 进行了一些有用的聊天,但我真的找不到任何真正解决我问题的解决方案。使用Polymer是一个非常好的主意,但不适合因为我需要支持较旧的 IE。
所以相反,我进入了猴子修补的危险世界来解决它(请记住,我可能需要用这个来消除一些皱纹,刚刚完成并没有完全测试它 - 我会相应地更新)
在 Coffeescript 中:(底部的 JavaScript 版本)
# Monkey patching the Marionette View.. sorry!
# this is the only Marionette view which doesn't have it's own constructor
Marionette.ItemView = Marionette.ItemView.extend
constructor: ->
Marionette.View.prototype.constructor.apply @, Array.prototype.slice.call(arguments, 0)
original_view_constructor = Marionette.View.prototype.constructor
Marionette.View.EventAggregator = event_aggregator = _.extend {}, Backbone.Events
# all the other constructors call this so we can hijack it
Marionette.View.prototype.constructor = ->
event_aggregator.listenTo @, 'all', =>
args_array = Array.prototype.slice.call arguments, 0
event_aggregator.trigger.apply event_aggregator, [ 'view:' + args_array[0], @ ].concat(args_array.slice(1))
event_aggregator.stopListening @ if args_array[0] == 'close'
original_view_constructor.apply @, Array.prototype.slice.call(arguments, 0)
然后使用我只需在我的应用程序对象中设置一个侦听器来捕获我需要的视图事件。例如:
@listenTo Marionette.View.EventAggregator, 'view:dom:refresh', (view) ->
view.$('div').css('backgroundColor', 'red');
所以在我看来,这些是这种技术的优点和缺点:
优点:
- 无需注入所有视图类或子类化所有视图类即可监听所有视图事件
- 使用简单
- 对象根本不需要选择使用它
缺点
- 使用猴子补丁,对 Marionette API 很危险
- 使用 Marionette 命名空间很容易受到未来 Marionette 命名空间冲突的影响
- 处理视图上下文之外的视图
- 在 Backbone/Marionette (afaiw) 的其他地方看不到事件聚合器对象,因此打破了模式(更新 - 在 Backbone.history 中可以看到类似的东西)
无论如何,我欢迎反馈、替代方案、批评 :-) 并希望这可能对处于相同情况的其他人有所帮助
Javascript:
(function() {
var event_aggregator, original_view_constructor;
Marionette.ItemView = Marionette.ItemView.extend({
constructor: function() {
return Marionette.View.prototype.constructor.apply(this, Array.prototype.slice.call(arguments, 0));
}
});
original_view_constructor = Marionette.View.prototype.constructor;
Marionette.View.EventAggregator = event_aggregator = _.extend({}, Backbone.Events);
Marionette.View.prototype.constructor = function() {
var _this = this;
event_aggregator.listenTo(this, 'all', function() {
var args_array;
args_array = Array.prototype.slice.call(arguments, 0);
event_aggregator.trigger.apply(event_aggregator, ['view:' + args_array[0], _this].concat(args_array.slice(1)));
if (args_array[0] === 'close') {
return event_aggregator.stopListening(_this);
}
});
return original_view_constructor.apply(this, Array.prototype.slice.call(arguments, 0));
};
}).call(this);