0.0.10 • Published 5 years ago
ember-cli-group-by v0.0.10
ember-cli-group-by
A group by computed property and helper that supports nested properties, e.g. model with a
belongsTo
relationship.
import Controller from '@ember/controller';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
arrayGrouped: groupByPath('array', 'nested.property'),
});
{{#each-in (group-by-path array "nested.property") as |category items|}}
<h3>{{category}}</h3>
<ul>
{{#each items as |item|}}
<li>{{item.name}}</li>
{{/each}}
</ul>
{{/each-in}}
Installation
Requires Ember 2.10 or higher, see Issue #2.
ember install ember-cli-group-by
Usage
General
Computed property
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
cartGrouped: groupByPath('cart', 'category'),
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
]);
},
});
{{#each-in cartGrouped as |category products|}}
<h3>{{category}}</h3>
<ul>
{{#each products as |product|}}
<li>{{product.name}}</li>
{{/each}}
</ul>
{{/each-in}}
Handlebars helper
import Controller from '@ember/controller';
import { A } from '@ember/array';
export default Controller.extend({
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
]);
},
});
{{#each-in (group-by-path cart "category") as |category products|}}
<h3>{{category}}</h3>
<ul>
{{#each products as |product|}}
<li>{{product.name}}</li>
{{/each}}
</ul>
{{/each-in}}
Default Category
The group name for an item can be overridden by implementing a computed property function or by passing a closure action to the helper.
Computed property
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { isNone } from '@ember/utils';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
cartGrouped: groupByPath('cart', 'category', function (value) {
return isNone(value) ? 'Other' : value;
}),
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
{ name: 'Salt', category: null },
{ name: 'Sugar' },
]);
},
});
Handlebars helper
import Controller from '@ember/controller';
import { A } from '@ember/array';
import { isNone } from '@ember/utils';
export default Controller.extend({
init() {
this._super(...arguments);
this.set('cart', A([
{ name: 'Cinnamon ', category: 'Spice' },
{ name: 'Banana', category: 'Fruit' },
{ name: 'Apple', category: 'Fruit' },
{ name: 'Lettuce', category: 'Vegetable' },
{ name: 'Broccoli', category: 'Vegetable' },
{ name: 'Salt', category: null },
{ name: 'Sugar' },
]);
},
actions: {
defaultCategory(value) {
return isNone(value) ? 'Other' : value;
},
},
});
{{#each-in (group-by-path cart "category" (action "defaultCategory")) as |category products|}}
<h3>{{category}}</h3>
<ul>
{{#each products as |product|}}
<li>{{product.name}}</li>
{{/each}}
</ul>
{{/each-in}}
Async Relationship Property
The group by property path can be a nested belongsTo
relationship that is loaded asynchronously.
Check out the example at ember-twiddle.
// models/user.js
export default Model.extend({
fullname: attr('string'),
cart: hasMany('product', { inverse: 'shopper' }),
});
// models/product.js
export default Model.extend({
name: attr('string'),
category: belongsTo('category'),
shopper: belongsTo('user', { inverse: 'cart' }),
});
// models/category.js
export default Model.extend({
name: attr('string'),
});
import Controller from '@ember/controller';
import { isNone } from '@ember/utils';
import { alias } from '@ember/object/computed';
import { groupByPath } from 'ember-cli-group-by/macros';
export default Controller.extend({
user: alias('model'),
cart: alias('user.cart'),
cartGrouped: groupByPath('cart', 'category.name', function (value) {
return isNone(value) ? 'Other' : value;
}),
});