Reputation: 3311
Hello I have a layout view that has many filter partials and a collection. filter partials are shared across my project so they all reference "filter:change" as there trigger.
However, I am finding that when I change page and cause a "filter:change" I get issues with the previous view vent binds being called (and by then the template is removed from the dom).
Basically, when my my layout view closes I need to unbind the event "filter:change" so that the next layoutview can exclusively access that trigger.
Current code:
define([
"text!app/templates/users/index.html",
'app/views/users/collection',
'app/views/users/partials/internal',
'app/views/users/partials/enabled',
'app/views/partials/location_id'
],
function(Template, CollectionView, FilterInternalView, FilterEnabledView, FilterLocationIdView) {
"use strict"
return Backbone.Marionette.Layout.extend({
template: Template,
regions: {
filterInternal: '#filterInternalContainer',
filterEnabled: '#filterEnabledContainer',
filterLocationId: '#filterLocationIdContainer',
collectionLatch: '#collectionLatch'
},
initialize: function() {
// horrible scope issues with javascript
var that = this;
// if the filter change event is triggered in a sub view
MyApp.vent.on('filter:change', function() {
// fetch the collection and pass its filters through
that.renderCollection(that.getFilter());
})
},
getFilter: function() {
// create our new filter object using jQuery picking the values
var filter = {
from: "0",
to: parseInt(100),
enabled: $('#filterEnabled').val(),
internal: $('#filterInternal').val(),
location_id: $('#filterLocationId').val()
};
// passing it through a null stripper
filter = _.cleanNullFieldsFromObject(filter);
// set the filter object to local storage (extended, not typical)
localStorage.setObject('userFilter', filter);
return filter;
},
renderFilterEnabled: function(options) {
this.filterEnabled.show(new FilterEnabledView(options));
},
renderFilterInternal: function(options) {
this.filterInternal.show(new FilterInternalView(options));
},
renderFilterLocationId: function(options) {
this.filterLocationId.show(new FilterLocationIdView(options));
},
renderCollection: function(options) {
// render the post list
this.collectionLatch.show(new CollectionView(options));
},
onRender: function () {
// do we need to over write the filter object from local storage?
var userFilter = localStorage.getObject('userFilter');
// if local storage isn't empty then over ride the filter with it
if (!_.isEmpty(userFilter)) {
this.filter = userFilter;
} else {
this.filter = this.getFilter();
}
// render the filters on our page
this.renderFilterEnabled(this.filter);
this.renderFilterInternal(this.filter);
this.renderFilterLocationId(this.filter);
// render the collection
this.renderCollection(this.filter);
},
onClose: function() {}
})
})
// partial view
define(["marionette", "text!app/templates/partials/location_id.html", 'app/models/location'],
function(Marionette, Template, Model) {
"use strict"
return Backbone.Marionette.ItemView.extend({
template: Template,
events: {
'change #filterLocationId': 'onFilter'
},
initialize: function(options) {
this.value = _.isEmpty(options) ? '-' : options.location_id;
},
onFilter: function() {
MyApp.vent.trigger('filter:change');
},
serializeData: function() {
return {values: new Model().getIds(), value: this.value};
}
})
})
I looked at the documentation: https://backbonemarionette.readthedocs.org/en/latest/marionette.eventbinder.html#unbind-a-single-event
and tried:
onClose: function() {
MyApp.vent.off('filter:change');
}
but no matter what, even if the next view turns that vent back on, the event doesn't work.
Upvotes: 0
Views: 421
Reputation: 4129
Try to change the :
MyApp.vent.on('filter:change', function() {
// fetch the collection and pass its filters through
that.renderCollection(that.getFilter());
})
by
this.listenTo(MyApp.vent, 'filter:change', function() {
// fetch the collection and pass its filters through
that.renderCollection(that.getFilter());
})
Upvotes: 1