Skip to content

Instantly share code, notes, and snippets.

@2468ben
Created April 8, 2016 23:12
Show Gist options
  • Save 2468ben/0855177da7ecba88db6743e6e311e119 to your computer and use it in GitHub Desktop.
Save 2468ben/0855177da7ecba88db6743e6e311e119 to your computer and use it in GitHub Desktop.
2468ben's query param setup
/* global getOwner */
import Em from 'ember';
import _ from 'lodash/lodash';
export default Em.Mixin.create({
'query-params': Em.inject.service(),
qpRouteName: null,
enteredRoute: false,
onInit: Em.on('init', function() {
this.set('queryParamDefaults', this.currentQPs());
}),
/* This function gets the current set of queryParams, called on init to get the defaults,
and called on queryParamChanged to get the latest values.
I would use this.paramsFor(this.routeName) but this.routeName is undefined on my index route
and this.paramsFor('index') also fails. So until I can figure out why the index route fights back,
I manually set a 'qpRouteName' prop and use that instead of this.routeName. And then I do getOwner().lookup
to get the controller and the query params. Or get('container').lookup on older Ember versions.
Infinite thanks to anyone who can tell me why my index route's routeName might be undefined.
*/
currentQPs() {
const _owner = getOwner(this);
if(!_owner) { return null; }
const _controller = _owner.lookup(`controller:${this.get('qpRouteName')}`);
if(!_controller) { return null; }
return _controller.getProperties(_controller.get('queryParams'));
},
/*
I have had issues with queryParamsDidChange actions when the route is being resolved, like this issue:
(https://github.com/emberjs/ember.js/issues/10945#issuecomment-105685679)
so I disable it for that first stretch and trigger a similar event in the afterModel hook.
Once the route is resolved, then I enable queryParamsDidChange actions.
*/
afterModel(model, transition) {
this.filterQPChanges(transition.queryParams, null, transition);
},
/*
Like described above, I wait until setupController is called (and the route is resolved)
before enabling queryParamsDidChange actions.
*/
setupController(controller, model) {
this._super(controller, model);
this.set('enteredRoute', true);
},
/*
This is the function that would tell the query-params service some QPs just changed.
*/
queryParamsChanged(changedQPs, transition) {
},
/*
Which QPs changed? I grab the new values and the defaults, then compare and contrast.
*/
filterQPChanges(changedQPs, removedQPs, transition) {
const _defaultQPs = this.get('queryParamDefaults');
const _currentQPs = this.currentQPs();
const _filteredQPs = {};
// if it's a changed QP that's in our route (not some other route, add that value to the hash
_.each(changedQPs, (v, k) => {
if(_.has(_currentQPs, k)) {
_filteredQPs[k] = v;
}
});
// if it's a removed QP that's in our route (not some other route, add the default value to the hash
_.each(removedQPs, (v, k) => {
if(_.has(_defaultQPs, k)) {
_filteredQPs[k] = _defaultQPs[k];
}
});
// finally, if the hash of changes isn't empty, let's do something with it, right?
if(!_.isEmpty(_filteredQPs)) {
this.queryParamsChanged(_filteredQPs, transition);
}
},
actions: {
queryParamsDidChange(changed, totalPresent, removed) {
if(this.get('enteredRoute')) {
this.filterQPChanges(changed, removed);
}
return true;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment