Observe+ (Now observes on nested objects/arrays!)
Observe+ is a library based on Object.observe/Array.observe that adds the following features:
- fine-grained observe on individual properties/index/event types
- observe nested objects and arrays
- pause/resume to do batch updates on the data structure before publishing all the events
- observe once to remove the event listener after an event has fired
- disposable pattern for removing listeners
What is Object.observe?
http://addyosmani.com/blog/the-future-of-data-binding-is-object-observe/
Reference: http://arv.github.io/ecmascript-object-observe/
Compatible browsers:
Check Kangax' ES compat' table to see where Object.observe (ES7) is available : http://kangax.github.io/es5-compat-table/es6/#Object.observe_(part_of_b_ES7_/b_)
Installation:
npm install observe-plus
How to use?
Remember that you need to have Object.observe and Array.observe in order for observe-plus to work:
In node.js
Run with the --harmony option:
node --harmony myscript.js
In Chrome
enable the harmony flag, navigate to chrome://flags/#enable-javascript-harmony
API
var observePlus = ;
Observing objects:
Object.observe() listens to changes happening on an object. Usually, we are interested in two types of events:
- When a property is added, updated, or removed from an object:
var object = {};// I want to know when a new property is addedobjectnewProperty = "value"; // and when a property is updatedobjectnewProperty = "newValue"; // or when it's removeddelete objectnewProperty;
- When the value of a specific property changes:
var object = property: "value"; // I want to observe object.property to know when the value changes:objectproperty = "newValue";objectproperty = "otherValue";
Observe+ allows to listen to these two types.
Observing generic events on the object such as property added, updated, removed:
var plainObject = {}; var observer = observePlus; // Listening to properties being added to the objectvar dispose = observer; // This will trigger the listeners that have subscribed to "add"plainObjectnewProperty = "value"; // This will add a listener to properties being updatedobserver; // This listener will be called only once and then disposed ofobserver; // This will trigger the listeners that have subscribed to "update"plainObjectnewProperty = "newValue"; // This listener will be called when a property is deleted from the objectobserver; // This listener will be called only once and then disposed ofobserver; // This will trigger the listeners that have subscribed to "delete"delete plainObjectnewProperty; // When you're done with a listener, you can remove it by calling the dispose function that is the observe() method returned.// All the observe methods return a dispose function.;
Observing changes on specific properties of the object:
// Listening to changes on the "newProperty" propertyvar dispose = observer; // Or similar, but the listener will be called only once:observer; // This will call the callback with the "add" eventplainObjectnewProperty = "value"; // This will call the callback with the "update" eventplainObjectnewProperty = "newValue"; // This will call the callback with the "delete" eventdelete plainObjectnewProperty; // This will not call the callback as it's not listening to events on anotherPropertyplainObjectanotherProperty = "value"; // When you're done with a listener, you can remove it by calling the dispose function that is the observe() method returned.// All the observe methods return a dispose function.;
Stop observing changes on this object:
observer;
Observing arrays:
As for arrays, we may be interested in:
- Listening to changes on the array such as item added/removed (splice) or updated (update):
var array = ;// I want to know when an item is added:array; // When an item is updatedarray0 = "updatedItem"; // When an item is removedarray;
- Listening to changes on a specific index of the array:
var array = "item"; // I want to know when array[0] is updated:array0 = "newValue";array0 = "otherValue";
Observing generic events on the array such as item added, updated, removed:
var plainArray = ; var observer = observePlus; // Listening to changes on the array such as item added or removedvar dispose = observer; // Listening to splice events only once:observer; // This will trigger all the listeners that have subscribed to "splice"plainArray; // Listening to updates on the itemsobserver; // This will trigger all the listeners that have subscribed to "update"plainArray0 = "newValue"; // This will again trigger all the listeners that have subscribed to "splice"plainArray; // When you're done with a listener, you can remove it by calling the dispose function that is the observe() method returned.// All the observe methods return a dispose function.;
Observing events on specific items from the array:
var dispose = observer; // Or to listen index 10 only once:observer; // This will trigger all the listeners that have subscribed to changes on item 10:plainArray10 = "item"; // Removing the listener;
Trick: if you use Object.observe on the array, you can also listen to "length" changes as it's a property of the object
var observer = observePlus; observer;
Stop observing changes:
observer;
Observing nested properties!
Observe+ can also watch for generic events or events on specific items/properties from nested objects and arrays!
Given this data structure:
var dataStructure = id: 0 name: "Alice" colors: "red" "green" id: 1 name: "Bob" colors: "yellow" "pink" id: 2 name: "Carol" colors: "purple" ;
I can watch this dataStructure:
var observer = object;
then I can watch if Alice's preferred color changes:
observer; // Will trigger the eventdataStructure0colors0 = "blue";
Pause/resume:
The events are fired asynchronously, on the next turn of the event loop. This should allow for rendering to be delayed until all computation is done. If you still want to delay the trigger further, you can pause the observer and resume it later, by using the pause/resume API:
// Pause the observerobserver; // do something on object/array; // resume the observer, which will trigger all the listeners with the events:observer;
Note that resume() will also trigger the callbacks asynchronously, to be consistent with Object.observe and Array.observe.
Changelog
3.0.4 - Beta - 04 APR 2015
- Tests are using setImmediate instead of asap, which fixes the failing tests with the latest node.js
3.0.3 - Beta - 08 MAR 2015
- All events have an oldValue property
3.0.2 - Beta - 05 MAR 2015
- Fix bug where oldValue was incorrectly resolved to undefined
3.0.1 - Beta - 05 MAR 2015
- Fix various bugs when modifying parent of observed nested objects that would prevent some events being properly published
3.0.0 - Beta - 25 FEB 2015
- Fix a bug preventing splice events from triggering
- Fix performance issue when triggering events for many event listeners
- Update documentation
3.0.0 - Alpha - 17 FEB 2015
- Can observe nested objects and arrays
- Add current value of the watched property to the event object
- Unified observeArray and observeObject using polymorphism
- Using destroy terminology instead of unobserve
- Add isPaused method
2.1.0 - 28 DEC 2014
- Added .observe that either uses observeArray or observeObject depending on the type of the model to watch
- [Breaking Change] observeIndex(Once) and observeProperty(Once) are renamed to observeValue(Once).
- [Breaking Change] Removed bower support and standalone versions of observe-plus for the browser.
2.0 - 28 DEC 2014
Beta versions
1.0.1 - 5 MAR 2014
- Now throws an error when trying to observe an object in a runtime that doesn't have Object.observe
1.0.0
first release
License:
MIT