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