我有一个带有大量视图的Marionette应用程序。我想在每个渲染时将调试消息记录到控制台(并且可能在将来,在其他事件上)
我目前通过从每个View的onRender
方法记录来执行此操作:
MyModule.MyViewType = Marionette.ItemView.extend({
// ... view properties and methods
onRender: function() {
// ... other onRender code
console.debug('MyModule.MyViewType %s %s', this.cid, 'render');
}
});
这有效,但它有几个缺点:
onRender
操作,所以我只是为了调试而添加方法。那感觉不对。show
,我需要为每个视图添加一个事件处理程序或一个新方法。有没有办法记录每个视图渲染而不向每个视图添加代码?
答案 0 :(得分:5)
是。您可以decorate Backbone.View.constructor
加入View创建生命周期。然后,您可以为所有View实例上的任何事件注册回调。
!function() {
// Development: log view renders and other events
// Don't execute this function in production.
// Save a reference to the original Backbone.View and create a new type
// that replaces the constructor method
var OriginalView = Backbone.View,
LoggingView = OriginalView.extend({
constructor: function() {
// Execute the original constructor first
OriginalView.apply(this, arguments);
// Allow views to define a `type` property to clarify log messages
var type = this.type || 'Unknown View Type',
cid = this.cid;
// Bind to Marionette.View's `render` event (and any other events)
this.listenTo(this, 'render', function(e,b) {
console.debug('%s %s - %s', type, cid, 'render');
});
}
});
// Replace Backbone.View with our decorated view
Backbone.View = LoggingView;
}();
要记录视图类型,请在View实现中添加属性:
MyModule.MyViewType = Marionette.ItemView.extend({
type: 'MyModule.MyViewType',
// ... rest of the view code
});
可靠地确定JavaScript的对象“type”(构造函数名称)是problematic,因此添加此属性是确定正在呈现的视图类型的最佳方法。
通过提供您要记录的事件数组,可以很容易地将此答案推广到多个事件类型:
var events = ['render', 'show', 'beforeClose'];
events.forEach(function(eventType) {
this.listenTo(this, eventType, function() {
console.debug('%s %s - %s', type, cid, eventType)
});
}).bind(this);
示例输出:
Projects.ViewType1 view13 - render
Projects.ViewType2 view3 - render
Projects.ViewType3 view6 - render
Projects.ViewType4 view9 - render
Projects.ViewType4 view17 - render
Projects.ViewType4 view19 - render
Projects.ViewType2 view3 - render
这种方法解决了问题中描述的所有问题 - 代码量很少,视图不需要直接修改,只有一个函数调用可以省略,以删除生产代码中的日志记录。
这种方法特定于Marionette - 因为vanilla Backbone的render
方法是用户定义的,没有等同于render
事件。
有关扩展Backbone构造函数方法的更多详细信息,请参阅Derick Bailey's blog。