Observe changes in your applications.
Aurelia provides a multitude of different wants to observe properties in your components and call a callback function when they change.
The following sections in the observation documentation will help you decide which observation strategy is appropriate for your applications, from the most commonly used to more advanced observation strategies.
The easiest way to watch for changes to specific view model properties is using the @observable
decorator which provides an easy way to watch for changes to properties and react accordingly.
While still using the @observable
API, the effect observation approach has more boilerplate and is convenient for instances where you want to observe one or more effects. Examples include when the user moves their mouse or other changes you might want to watch, independent of the component lifecycle.
Unlike other forms of observation, HTML observation is when you want to watch for changes to specific properties on elements, especially for web component properties.
The observer locator API allows you to observe properties for changes manually. In many instances, you will want to use @observer
or @watch
however, the observer locator can be useful in situations where you want to watch the properties of objects.
Learn how to work with Aurelia's observable decorator to create reactive properties inside your component view models that have change callbacks.
Unlike the @watch decorator, the @observable
decorator allows you to decorate properties in a component and optionally call a change callback when the value changes. It works quite similarly to the @bindable
property.
By convention, the change handler is a method whose name is composed of the property_name and the literal value 'Changed'. For example, if you decorate the property color
with @observable
, you have to define a method named colorChanged()
to be the change handler.
This is what a basic observable would look like using conventions:
When the color
value is changed, the colorChanged
callback will be fired. The new changed value will be the first argument, and the existing one will be the second one.
If you prefer, you can also put the @observable
decorator on classes:
You do not have to check if newValue
and oldValue
are different. The change handler will not be called if you assign a value the property already has.
If you do not want to use the convention, you can define the callback name for the change handler by setting the callback
property of the @observable
decorator:
Loading...
HTML elements are special objects that often require different observation strategies, and most of the time, listening to some specific event is the preferred way. For this reason, Aurelia encourages using events to observe HTML elements.
As an example, the value
property of an <input />
element should be observed by listening to the <input />
change events such as input
or change
on the element. Another example is the value
property of a <select />
element should be observed by listening to the change
event on it.
By default, the observation of HTML elements is done using a default node observer locator implementation. This default locator has a basic set of APIs that allows users to teach Aurelia how to observe HTML element observation effectively.
The following is the trimmed interface of the node observer locator, highlighting its capability to learn how to observe HTML elements:
useConfig
and useConfigGlobal
are two methods that can be used to teach the default node observer locator what events can be used to observe a property of a specific element or any element.
Using the nodeObserverLocator
API, we can tell Aurelia how to observe properties of HTML elements for changes. Under the hood, Aurelia already observes properties like values on form inputs, but it is good to understand how this functionality works, especially for custom elements and web components.
value
property of a <textarea />
element:In this example, the eventsConfig
argument has the value { events: ['input', 'change']}
.
length
of an <input />
element:In this example, eventsConfig
argument has the value { events: ['input']}
.
scrollTop
of all elements:In this example, eventsConfig
argument has the value { events: ['scroll']}
.
It should be the same as observing custom (HTML) elements and normal HTML elements. It is common for Web Components to have well-defined events associated with their custom properties, so observing them often means adding a few configuration lines.
An example of how to teach Aurelia to observe the value
property of a <my-input />
element, and <my-input />
dispatches valueChanged
event when its value has been changed:
Loading...
Aurelia provides a higher-level API for simplifying some common tasks to handle a common reactivity intent in any application: run a function again when any of its dependencies have been changed.
This function is called an effect, and the dependencies are typically tracked when they are accessed (read) inside this effect function. The builtin @observable
decorator from Aurelia enables this track-on-read capability by default.
Aurelia provides a few ways to declare a dependency for an effect function. The most common one is the track "on read" of a reactive property.
In the following example:
The property coord
of a MouseTracker
instance will be turned into a reactive property and is also aware of effect function dependency tracking.
Properties decorated with @observable
and any proxy based property accesses will be tracked as dependencies of the effect
The effect APIs are provided via the default implementation of the interface IObservation
, which can be retrieved like one of the following examples:
Getting from a container directly:
Getting through injection:
Or
After getting the observation object, there are two APIs that can be used to created effects as described in the following sections:
Watch effect is a way to describe a getter based observation of an object. An example to create watch effect is per the following:
Note that the effect function will be run immediately. If you do not want to run the callback immediately, pass an option immediate: false
as the 4th parameter:
By default, a watch effect is independent of any application lifecycle, which means it does not stop when the application that owns the observation
instance has stopped. To stop/destroy an effect, call the method stop()
on the effect object.
Run effects describe a function to be called repeatedly whenever any dependency tracked inside it changes.
After getting an IObservation
instance, a run effect can be created via the method run
of it:
Note that the effect function will be run immediately.
By default, a effect is independent of any application lifecycle, which means it does not stop when the application that owns the observation
instance has stopped. To stop/destroy an effect, call the method stop()
on the effect object:
The following section gives some examples of what it looks like when combining @observable
and run effect.
Now whenever the user moves the mouse around, a log will be added to the console with the coordinate of the mouse.
The Observer Locator API allows you to watch properties in your components for changes without the need for using the @observable
decorator. In most cases, manual observation will not be required using this API, but it is there if you want it.
By default, an observer locator is used to create observers and subscribe to them for change notification.
A basic observer has the following interface:
The subscribe
method of an observer can be used to subscribe to the changes that it observes. This method takes a subscriber as its argument.
A basic subscriber has the following interface:
An observer of an object property can be retrieved using an observer locator.
An example of this is:
And to subscribe to changes emitted by this observer:
It's not always sufficient to observe a single property on an object, and it's sometimes more desirable to return a computed value from the source so that subscribers of an observer don't have to perform any logic dealing with the updated values. An example of this is the follow observation of firstName
and lastName
to notify full name:
Doing it the way above is cumber some as we need to setup 2 observers and 2 subscribers, also there's a typo risk. We can also use a getter to express a computed value, and then observe that getter to avoid having to do heavy setup work:
This is not always feasible since the obj could be from a 3rd party library, or some json data from server, and the risk of having a typo fullName
is still there.
Aurelia provides another API of creating observer to deal with this scenario, where it's more desirable to use a function/lambda expression to express the dependencies and computed value to notify the subscriber. To use this API, replace the 2nd parameter of getObserver
with a getter function to express the value:
Sometimes it's more desirable to work with a higher level API, for this consider using watch