Function
tracked public
Defined in packages/@ember/-internals/glimmer/lib/glimmer-tracking-docs.ts:22
import { tracked } from '@glimmer/tracking'; |
Marks a property as tracked. By default, values that are rendered in Ember app templates are static, meaning that updates to them won't cause the application to rerender. Marking a property as tracked means that when that property changes, any templates that used that property, directly or indirectly, will rerender. For instance, consider this component:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import Component from ' /component'; import { tracked } from ' /tracking'; import { action } from ' /object'; export default class CounterComponent extends Component { count = 0; get timesTen() { return this.count * 10; } plusOne() { this.count += 1; } } |
Both the {{this.count}}
and the {{this.timesTen}}
properties in the
template will update whenever the button is clicked. Any tracked properties
that are used in any way to calculate a value that is used in the template
will cause a rerender when updated - this includes through method calls and
other means:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; class Entry { name; phoneNumber; constructor(name, phoneNumber) { this.name = name; this.phoneNumber = phoneNumber; } } export default class PhoneBookComponent extends Component { entries = [ new Entry('Pizza Palace', 5551234), new Entry('1st Street Cleaners', 5554321), new Entry('Plants R Us', 5552468), ]; // Any usage of this property will update whenever any of the names in the // entries arrays are updated get names() { return this.entries.map(e => e.name); } // Any usage of this property will update whenever any of the numbers in the // entries arrays are updated get numbers() { return this.getFormattedNumbers(); } getFormattedNumbers() { return this.entries .map(e => e.phoneNumber) .map(number => { let numberString = '' + number; return numberString.slice(0, 3) + '-' + numberString.slice(3); }); } } |
It's important to note that setting tracked properties will always trigger an update, even if the property is set to the same value as it was before.
1 2 3 4 5 |
let entry = new Entry('Pizza Palace', 5551234); // if entry was used when rendering, this would cause a rerender, even though // the name is being set to the same value as it was before entry.name = entry.name; |
tracked
can also be used with the classic Ember object model in a similar
manner to classic computed properties:
1 2 3 4 5 6 7 |
import EmberObject from '@ember/object'; import { tracked } from '@glimmer/tracking'; const Entry = EmberObject.extend({ name: tracked(), phoneNumber: tracked() }); |
Often this is unnecessary, but to ensure robust auto-tracking behavior it is advisable to mark tracked state appropriately wherever possible.
This form of tracked
also accepts an optional configuration object
containing either an initial value
or an initializer
function (but not
both).
1 2 3 4 5 6 7 8 9 |
import EmberObject from '@ember/object'; import { tracked } from '@glimmer/tracking'; const Entry = EmberObject.extend({ name: tracked({ value: 'Zoey' }), favoriteSongs: tracked({ initializer: () => ['Raspberry Beret', 'Time After Time'] }) }); |