Updated 2019-01-22: updated for ember-decorators 5.0
ember-decorators
offers a lot of different decorators to allow you to indicate metadata to Ember about your ES6 classes, properties, and methods. I find myself checking the documentation for these a lot, so I thought I’d combine all the common decorators I use in one place. First is a quick reference of all of their imports for easy copying-and-pasting, and then is an example of usage of each.
Import Reference
import { tagName } from '@ember-decorators/component';
import { attr, belongsTo, hasMany } from '@ember-decorators/data';
import { action, computed } from '@ember-decorators/object';
import { filterBy, sort } from '@ember-decorators/object/computed';
import { inject as service } from '@ember-decorators/service';
Examples
Note that these decorators are not necessarily limited to use with the class types I use in these examples; these were just convenient classes to illustrate them.
@tagName
lets you designate the outer wrapping tag for a component, or''
to not use an outer wrapping tag.@action
lets you designate a method as an action available to be called from the template.@computed
creates a computed property. Note that the property needs to specified as an ES5 getter, with theget
keyword. You pass the properties the computed property depends on to the decorator.
import Component from '@ember/component';
import { tagName } from '@ember-decorators/component';
import { action, computed } from '@ember-decorators/object';
@tagName('')
export default class LinkRow extends Component {
editing = false;
@computed('link.read')
get showLink() {
return this.showIfRead === this.link.read;
}
@action
edit() {
this.set('editing', true);
}
@action
finishEditing() {
this.set('editing', false);
}
}
@filterBy
filters an array by a property/value pair.@sort
allows you to sort an array using an array of fields to sort by, or a predicate function.
import Controller from '@ember/controller';
import { filterBy, sort } from '@ember-decorators/object/computed';
export default class PastReadingsController extends Controller {
completionOrder = Object.freeze(['completed_at:desc']);
@filterBy('model', 'complete', true)
pastReadings;
@sort('pastReadings', 'completionOrder')
pastReadingsInCompletionOrder;
}
@attr
allows you to designate Ember Data model attributes, optionally specifying a transformation.@belongsTo
and@hasMany
allows you to specify Ember Data relationships, passing the name of the related model.
import DS from 'ember-data';
const { Model } = DS;
import { attr, belongsTo, hasMany } from '@ember-decorators/data';
export default class Bookmark extends Model {
@attr url;
@attr('date') published_at;
@belongsTo('user') user;
@hasMany('tag') tags;
}
@inject
allows you to inject a dependency, by default using the name of the property as the dependency name to look up. One of the most common uses is to inject services. In that case, it’s common practice to alias the director toservice
upon import, so that you can write@service
;
import Route from '@ember/routing/route';
import { inject as service } from '@ember-decorators/service';
export default class IndexRoute extends Route {
@service session;
model() {
if (this.session.isAuthenticated) {
return this.store.findAll('reading');
}
}
}