javascript - Bubbling events in nested Backbone (Marionette) Models / Collections -
we have large marionette app, uses backbone.trackit
monitor unsaved changes in our models.
we have nested models, in fact have model, collection of models, contain collection of models.
trackit
doesn't support top level model being marked 'dirty' when child models change - due backbone not bubbling these change events.
i know manually monitor these change events, im looking generic solution.
has had experience of following libs or other solutions this?
- backbone-deep-model
- backbone associations events
- custom backbone.model.set override bubbles change events
the immediate requirement trackit
working nested events - cant find branches trackit
add this.
so wondering if has approached this, or used above libs in conjunction trackit
?
ideally, if library trigger standard 'change' event way chain, trackit
pick on , start working.
so, if model.countries[3].regions[4].name
changed, change:countries
event triggered on model
. if model had trackit
enbaled, work!
the events models inside collection bubbles collection default. that's 1 thing solved , need bubble events collection or model inside model.
one problem see bubbling events as-is hierarchy false positive when want listen that specific collection or model.
a way avoid namespace events bubbling up, may not work trackit.
a simple implementation of model enables bubbling events of arbitrary collections or other nested models:
var bubblingmodel = backbone.model.extend({ /** * bubbles event triggered 'object'. * @param {backbone.events} obj implement backbone events. * @param {string} key optional namespace name, default 'nested'. */ addnested: function(obj, key) { return this.listento(obj, 'all', function() { arguments[0] = (key || 'nested') + ':' + arguments[0]; this.trigger.apply(this, arguments); }); }, removenested: function(obj) { return this.stoplistening(obj); } });
and use it:
var collection = new backbone.collection(), model = new bubblingmodel(); model.addnested(collection, 'optional-key');
any events collection
prefixed optional key
or default nested
string. change:myattribute
event triggered collection
be:
"optional-key:change:myattribute"
proof of concept simple tests:
// simple implementation var bubblingmodel = backbone.model.extend({ /** * bubbles event triggered 'object'. * @param {backbone.events} obj implement backbone events. * @param {string} key optional namespace name, default 'nested'. */ addnested: function(obj, key) { return this.listento(obj, 'all', function() { arguments[0] = (key || 'nested') + ':' + arguments[0]; this.trigger.apply(this, arguments); }); }, removenested: function(obj) { return this.stoplistening(obj); } }); // setting test multiple nesting var model5 = new backbone.model(), model4 = new backbone.model(), model3 = new bubblingmodel({ model: model4 }), col2 = new backbone.collection([model3]), model2 = new bubblingmodel({ col: col2 }), col1 = new backbone.collection([model2]), model1 = new bubblingmodel({ col: col1 }); // set want bubble up. model3.addnested(model4, 'model3-nested-model'); model2.addnested(col2, 'model2-nested-col') .addnested(model5); model1.addnested(col1, 'model1-nested-col'); // listen model down chain backbone.listento(model2, 'all', function(eventname) { console.log("model2:", eventname); }); backbone.listento(model1, 'all', function(eventname) { console.log("model1:", eventname); }); // trigger default or custom events model3.set('test', 1); model3.trigger('model3'); model4.trigger('model4'); model5.trigger('model5');
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>
Comments
Post a Comment