javascript - Marionette - Events being triggered multiple times -
i'm having troubles handling events between views , collections. in below example can find short version of webapp , how events being handled now.
what happens here when switching menu1 menu2 or when going backwards, causes "app:change_city" event listener stacked up. when trigger event , calls method oncitychange() many times switched between menus.  
i'm not sure whether i'm using event aggregator (emgr) correctly. can please assist?
emgr.js
define(['backbone.wreqr'],function(wreqr){     "use strict";     return new wreqr.eventaggregator(); }) approuter.js
define(['marionette'],  function (marionette) {     "use strict";      var approuter = marionette.approuter.extend({         approutes: {             'menu1' : 'showmenu1',             'menu1' : 'showmenu2'         }     });      return approuter; }); appcontroler.js
define(['underscore', 'backbone', 'marionette', '../emgr'],  function (_, backbone, marionette, emgr) {     "use strict";      var controller = marionette.controller.extend({             initialize: function(){                 console.log("approuter - init")             },              showmenu1: function (city) {                 console.log(" [info] [appcontroler] opening menu1");                 emgr.trigger("app:open_menu", { menu: "menu1", city: city});             },              showmenu2: function (city) {                 console.log(" [info] [appcontroler] opening menu2");                 emgr.trigger("app:open_menu", { menu: "menu2", city: city});             }     });      return controller; }); app.js
define([ 'backbone', 'underscore', 'marionette', 'emgr',       'layouts/mainmenu/layoutview.menu1',     'layouts/mainmenu/layoutview.menu2',     'controllers/appcontroller', 'routers/approuter'],      function (backbone, _, marionette,  emgr,       lv_mainmenu1, lv_mainmenu2,     appcontroller, approuter) {     "use strict";      var myapp = new marionette.application();     var controller = new appcontroller();      myapp.addregions({         .....         mainmenu: '#main_menu',         .....     });      myapp.listento(emgr, "menu_changed",function(edata){         switch(edata.menu){             case "menu1":                 myapp.mainmenu.show(new lv_mainmenu1(edata));                 break;             case "menu2":                  myapp.mainmenu.show(new lv_mainmenu2(edata));                 break;         }     });      myapp.addinitializer(function(options) {         var router = new approuter({           controller : controller         });     });       myapp.on("start", function(){       if (backbone.history){           backbone.history.start();       }     });      $(document).ready(function() {         myapp.start();     }); }); layoutview.menu1.js
define([ 'backbone', 'underscore', 'marionette',              'templates/template.mainmenu',              'layouts/mainmenu/collectionview.categories'],     function (backbone, _, marionette, t_menus, c_categories, cv_categories) {     "use strict";     var menu1layoutview = marionette.layoutview.extend({          template: t_menus['menu1'],          regions: {             menu : '#menu'         },          initialize: function(options){             this.city = options.city         },           onrender: function(){         },          onshow: function(){             this.menu.show(new cv_categories({city:this.city}));         }     });      return menu1layoutview; }); collectionview.categories.js
define([ 'backbone', 'underscore', 'marionette',     'layouts/mainmenu/compositeview.subcategories',     'collections/mainmenu/mm.collection.categories'],      function (backbone, _, marionette, cv_subcategories, c_categories) {     "use strict";     var categoriescollectionview = marionette.collectionview.extend({          initialize: function(options){             this.collection = new c_categories([], {city: options.city});         },          getchildview: function(model){             return cv_subcategories;         },          onrender: function(){         },          onshow: function(){         }     });      return categoriescollectionview; }); this categorie's data fetched , re-fetches data once app:change_city event being triggered. 
mm.collection.categories.js
    define([ 'underscore',  'backbone', 'emgr','models/mainmenu/mm.model.category'], function(_, backbone, emgr, m_category){   var categoriescollection = backbone.collection.extend({     model: m_category,      initialize: function(attr, opts) {         this.city = opts.city;         this.fetch();         emgr.once("app:change_city", this.oncitychange, this)     },      url: function(){         return 'af_getcategories?city='+this.city;     },      oncitychange: function(edata){         /// part being called multiple times !!!!!   ////         /// when checking emgr's events , shows events stacking ..          this.url= 'af_getcategories?city='+edata.city;         this.fetch();     }   });    return categoriescollection; }); compositeview.subcategories.js
define([ 'backbone', 'underscore', 'marionette',     'templates/template.mainmenu',      'layouts/mainmenu/itemview.subcategory'],      function (backbone, _, marionette, t_mainmenu, iv_subcategory) {     "use strict";     var subcategoriescompositeview = marionette.compositeview.extend({          template: t_menus['subcategorieslayout'],          childviewcontainer: "#category-wrapper",          getchildview: function(model){             return iv_subcategory;         },          initialize: function(){             this.collection = this.model.get("subcategories");         },           onrender: function(){         },          onshow: function(){             this.$el.find("#loading").fadeout(150);         }     });      return subcategoriescompositeview; }); 
i have come conclusion keeping event listeners this.listento("custom_event", this.do_something) in either model or collection isn't idea. events weren't cleaned while switching between menu1 , menu2. worked when manually called emgr.stoplistening()  before loading views. 
so tried moving event listeners models/collections views , voila!...it worked! events no longer being triggered multiple times before. 
Comments
Post a Comment