marionette - Better to call child view method directly from parent, or by initiating a trigger? -
i've got complex backbone/marionette app , i'm venting things out parent elements . when need trigger things in children parent elements though, it's little unclear me how should doing this. easiest thing call method on child parent, but, wonder if "cheating" in case (and perhaps causing memory leak issues or something?) , i'm curious "right" way.
here's jsfiddle of extremely simplified contrived version of code. a gist of same contrived example in require based app.
<header> <h4>a subview/view trigger event loop playground</h4> <p>open console , click button</p> </header> <article id="main"> </article> <script type="text/html" id="mysubview"> <button type="button" id="button">click me</button> </script> <script type="text/html" id="myview"> <div id="myregion"></div> </script> <script> var app = new marionette.application(); app.addregions({ "mainregion": "#main" }); app.module("samplemodule", function(mod, app, backbone, marionette, $, _){ var mysubview = marionette.itemview.extend({ template: '#mysubview', events: { 'click #button': 'sendclick' }, triggers: { 'afterclick': 'afterclick' }, initialize: function initialize(){ this.on('afterclick', this.afterclick); }, sendclick: function(e) { e.preventdefault(); console.log('good... use ventful capabilities boy...'); //trigger method in parent... this.trigger('processclick'); }, afterclick: function(who) { console.log("i've been waiting you... circle complete. when left sender, receiver...", who); } }); var myview = marionette.layout.extend({ template: '#myview', views: {}, regions: { myregion: '#myregion' }, onshow: function onshow(){ this.views.mysubview = new mysubview({ model: this.model }).on('processclick', this.sendbackclick, this); this.myregion.show(this.views.mysubview); }, sendbackclick: function(){ //do stuff, then, let child know you're done... console.log('heh heh heh heh.... goood, goooood! triggers have made powerful. now, fulfil parents destiny , take event @ side!!!'); //use trigger? this.views.mysubview.trigger('afterclick', 'from trigger'); //call method directly? this.views.mysubview.afterclick('called directly'); } }); var controller = marionette.controller.extend({ initialize: function(options){ this.region = options.region }, show: function(){ var mainview = new myview({ model: new backbone.model({'prop':'value'}) }); this.region.show(mainview); } }); mod.addinitializer(function(){ mod.controller = new controller({ region: app.mainregion }); mod.controller.show(); }); }); app.start(); </script>
as aside: notice i'm using 'view' property on parent keep track of it's children. if there's better way this, or reason why that's wrong i'd love hear it.
a couple things may or may not answer question:
first, in contrived example it's pretty clear want child know 'click' has been processed parent, in real world guessing may not relevant piece of information. perhaps child should listening else altogether? example, layout , child view happen share model. i'm going take leap , guess click event meant kick off processing on model. if that's case maybe child wants know event triggered on model (either built-in or custom). in way child view appropriately respond event if didn't come click in first place (seems reasonable me there might someday multiple paths). granted, making lot of assumptions. if it's not model center of event still other child view - app.vent? parent layout itself? depends on exact use case.
second, watch out creating views object when define layout. shared reference between individual instances of layout instantiate. it's possible that's want, (assumptions again) i'm guess it's not.
Comments
Post a Comment