From c95c3e4e1e0fc8b72902f1d055320554b96957cf Mon Sep 17 00:00:00 2001 From: Rob Eisenberg Date: Wed, 18 Nov 2020 15:07:56 -0500 Subject: [PATCH] doc(fast-element): add section on array observation (#4128) * doc(fast-element): add section on array observation * doc(fast-element): export other needed APIs and document opt-in nature --- .../docs/guide/observables-and-state.md | 31 ++++++++++++++++++- .../web-components/fast-element/src/index.ts | 2 ++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/web-components/fast-element/docs/guide/observables-and-state.md b/packages/web-components/fast-element/docs/guide/observables-and-state.md index db1e7a03a45..b9fd8a906c4 100644 --- a/packages/web-components/fast-element/docs/guide/observables-and-state.md +++ b/packages/web-components/fast-element/docs/guide/observables-and-state.md @@ -143,9 +143,38 @@ notifier.subscribe(handler, 'firstName') notifier.unsubscribe(handler, 'lastName'); ``` +## Observing Arrays + +So far, we've only seen how to observe properties on objects, but it's also possible to observe arrays for changes. Given an instance of an array, it can be observed like this: + +**Example: Observing an Array** + +```ts +const arr = []; +const notifier = Observable.getNotifier(arr); +const handler = { + handleChange(source: any, splices: Splice[]) { + // respond to the change here + // source will be the array instance + // splices will be an array of change records + // describing the mutations in the array in + // terms of splice operations + } +}; + +notifier.subscribe(handler); +``` + +There are a couple of important details to note with array observation: + +* The `fast-element` library's ability to observe arrays is opt-in, in order that the functionality remain tree-shakeable. If you use a `repeat` directive anywhere in your code, you will be automatically opted in. However, if you wish to use the above APIs and are not using `repeat`, you will need to enable array observation by importing and calling the `enableArrayObservation()` function. +* The observation system cannot track changes made directly through an index update. e.g. `arr[3] = 'new value';`. This is due to a limitation in JavaScript. To work around this, update arrays with the equivalent `splice` code e.g. `arr.splice(3, 1, 'new value');` +* If the array is a property of an object, you will often want to observe both the property and the array. Observing the property will allow you to detect when the array instance is completely replaced on the object, while observing the array will allow you to detect changes in the array instance itself. When the property changes, be sure to unsubscribe to the old array and set up a subscription to the new array instance. +* Observing an array only notifies on changes to the array itself. It does not notify on changes to properties on objects held within the array. Separate observers would need to be set up for those individual properties. These could be set up and torn down in response to changes in the array though. + ## Bindings -In addition to watching basic properties, you can also watch arbitrary bindings. +In addition to watching properties and arrays, you can also watch arbitrary bindings. **Example: Subscribing to a Binding** diff --git a/packages/web-components/fast-element/src/index.ts b/packages/web-components/fast-element/src/index.ts index a199aac904c..04151851668 100644 --- a/packages/web-components/fast-element/src/index.ts +++ b/packages/web-components/fast-element/src/index.ts @@ -16,6 +16,8 @@ export { export * from "./view"; export * from "./observation/observable"; export * from "./observation/notifier"; +export { Splice } from "./observation/array-change-records"; +export { enableArrayObservation } from "./observation/array-observer"; export { DOM } from "./dom"; export * from "./directives/behavior"; export * from "./directives/binding";