javascript - How can I log a message on every Marionette view render? -
i have marionette application large number of views. want log debug message console when each rendered (and possibly, in future, on other events)
i doing logging each view's onrender
method:
mymodule.myviewtype = marionette.itemview.extend({ // ... view properties , methods onrender: function() { // ... other onrender code console.debug('mymodule.myviewtype %s %s', this.cid, 'render'); } });
this works, has several disadvantages:
- the logging code must added manually each view.
- several views don't have custom
onrender
actions i'm adding methods purpose of debugging only. feels wrong. - if want alter or remove logging methods (e.g. go production), need alter lot of code.
- if want add code event, e.g.
show
, need add event handler or new method every view.
is there way log every view render without adding code each view?
yes. can decorate backbone.view.constructor
hook view creation lifecycle. can register callbacks event on view instance..
!function() { // development: log view renders , other events // don't execute function in production. // save reference original backbone.view , create new type // replaces constructor method var originalview = backbone.view, loggingview = originalview.extend({ constructor: function() { // execute original constructor first originalview.apply(this, arguments); // allow views define `type` property clarify log messages var type = this.type || 'unknown view type', cid = this.cid; // bind marionette.view's `render` event (and other events) this.listento(this, 'render', function(e,b) { console.debug('%s %s - %s', type, cid, 'render'); }); } }); // replace backbone.view our decorated view backbone.view = loggingview; }();
to log view types, add property view implementations:
mymodule.myviewtype = marionette.itemview.extend({ type: 'mymodule.myviewtype', // ... rest of view code });
reliably determining javascript's object "type" (constructor name) problematic, adding property best approach determine type of view being rendered.
this answer generalised multiple event types providing array of events want logged:
var events = ['render', 'show', 'beforeclose']; events.foreach(function(eventtype) { this.listento(this, eventtype, function() { console.debug('%s %s - %s', type, cid, eventtype) }); }).bind(this);
example output:
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
this approach solves of problems described in question - there a small amount of code, views don't need altering directly , there single function call can omitted remove logging in production code.
this approach specific marionette - because vanilla backbone's render
method user-defined there no equivalent of render
event.
for more detail on extending backbone constructor methods see derick bailey's blog.
Comments
Post a Comment