New breadcrumb service and component for describing breadcrumbs in routes

Works by segmenting the currentRouteName from the router service
and walking over each route in the current hierarchy to collect crumbs.
This commit is contained in:
Michael Lange 2018-06-19 18:07:09 -07:00
parent be65653694
commit 865105734e
3 changed files with 57 additions and 0 deletions

View file

@ -0,0 +1,11 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { reads } from '@ember/object/computed';
export default Component.extend({
breadcrumbsService: service('breadcrumbs'),
tagName: '',
breadcrumbs: reads('breadcrumbsService.breadcrumbs'),
});

View file

@ -0,0 +1,37 @@
import { getOwner } from '@ember/application';
import Service, { inject as service } from '@ember/service';
import { computed } from '@ember/object';
export default Service.extend({
router: service(),
breadcrumbs: computed('router.currentRouteName', function() {
const owner = getOwner(this);
const allRoutes = this.get('router.currentRouteName')
.split('.')
.map((segment, index, allSegments) => allSegments.slice(0, index + 1).join('.'));
let crumbs = [];
allRoutes.forEach(routeName => {
const route = owner.lookup(`route:${routeName}`);
// Routes can reset the breadcrumb trail to start anew even
// if the route is deeply nested.
if (route.get('resetBreadcrumbs')) {
crumbs = [];
}
// Breadcrumbs are either an array of static crumbs
// or a function that returns breadcrumbs given the current
// model for the route's controller.
let breadcrumbs = route.get('breadcrumbs') || [];
if (typeof breadcrumbs === 'function') {
breadcrumbs = breadcrumbs(route.get('controller.model'));
}
crumbs.push(...breadcrumbs);
});
return crumbs;
}),
});

View file

@ -0,0 +1,9 @@
{{#each breadcrumbs as |breadcrumb index|}}
<li class="{{if (eq (inc index) breadcrumbs.length) "is-active"}}">
{{#link-to
params=breadcrumb.args
data-test-breadcrumb=breadcrumb.args.firstObject}}
{{breadcrumb.label}}
{{/link-to}}
</li>
{{/each}}