Filtering¶
Currently our interface shows us all modules and clicking on the “Current Semester” or “Last Semester” links has no effect. To get those working we will use Ember’s filtering functionality. In order to use that we need to explicitly define which query parameters our application supports. It is time to introduce a new concept in Ember: Controllers.
Controllers¶
In Ember, Controllers are used to provide route-wide logic.
They are routable objects that receive the returned value of the route’s model()
method.
Usually, their task is to decorate the model with display properties.
There is a 1-to-1 relationship between routes and controllers and they are connected by the shared name.
You can use Ember’s CLI to create a controller, by running
$ yarn ember generate controller modules
Update the app/controllers/modules.js
so that it looks like this:
import Controller from '@ember/controller';
export default class ModulesController extends Controller {
queryParams = ['semester'];
// set a default value
semester = undefined;
}
We specify that this controller supports one query parameter, namely “semester”. If you look at the app/models/module.js
, you will see that it has a “semester” property and that is what we will use for filtering. In the official documentation, the setup of the controller differs a little, since the query parameter is set to null
instead of undefined
, but our list of modules would be empty if we followed that tutorial since the initial request would end like this /modules?semester=
. Query params are only active witin the related route.
Next update theapp/routes/modules.js
:
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default class ModulesRoute extends Route {
@service store;
queryParams = {
semester: {
refreshModel: true,
},
};
model(params) {
return this.store.query('module', params);
}
}
We change the queryParams
definition. By default when query parameters change, the controller is notified, but the model is not automatically re-loaded from the server – useful when the query parameters just change aspects of what is displayed to the user. To force Ember to also re-load the data from the server, we need to set the refreshModel
property to true
.
Initially the query parameters are empty, so visually there is no change. In order to be able to select the query parameters, we update the app/components/modules/modules-navbar.hbs
to set the query parameters to the two relevant values:
As you can see, specific query parameters are set via the @query
parameter, which takes one or more parameter-value pairs. In our case we use the hash
helper to create such a pair. Now, test that by clicking on the two links, only the modules for that semester are displayed.
You might have already noticed, that the query parameters are sticky
. That means if you change the route and come back to the list of modules, the filter still applies. This behavior is on purpose. If you want to override this behavior, you need to update app/routes/modules.js
by adding this method after your model method:
/**
* Reset the controller when the route is changed.
*/
resetController(controller, isExiting) {
if (isExiting) {
controller.set('semester', undefined);
}
}