Warning: this library is experimental, and APIs are subject to change.

This library is used to observe changes to Observable types. It also has helpers to make implementing and using Observable objects easy.

You can provide an observable object in two ways. The simplest way is to use dirty checking to discover changes automatically:

class Monster extends Unit with ObservableMixin {
  @observable int health = 100;

  void damage(int amount) {
    print('$this takes $amount damage!');
    health -= amount;
  }

  toString() => 'Monster with $health hit points';
}

main() {
  var obj = new Monster();
  obj.changes.listen((records) {
    print('Changes to $obj were: $records');
  });
  // No changes are delivered until we check for them
  obj.damage(10);
  obj.damage(20);
  print('dirty checking!');
  Observable.dirtyCheck();
  print('done!');
}

A more sophisticated approach is to implement the change notification manually. This avoids the potentially expensive Observable.dirtyCheck operation, but requires more work in the object:

class Monster extends Unit with ChangeNotifierMixin {
  int _health = 100;
  get health => _health;
  set health(val) {
    _health = notifyPropertyChange(const Symbol('health'), _health, val);
  }

  void damage(int amount) {
    print('$this takes $amount damage!');
    health -= amount;
  }

  toString() => 'Monster with $health hit points';
}

main() {
  var obj = new Monster();
  obj.changes.listen((records) {
    print('Changes to $obj were: $records');
  });
  // Schedules asynchronous delivery of these changes
  obj.damage(10);
  obj.damage(20);
  print('done!');
}

Tools exist to convert the first form into the second form automatically, to get the best of both worlds.

Constants

observable → Object

Use @observable to make a field automatically observable.

const _ObservableAnnotation()

Typedefs

CompoundBindingCombinator(Map objects) → Object

The callback used in the CompoundBinding.combinator field.

Functions

toObservable(value, {bool deep: true}) → dynamic

Converts the Iterable or Map to an ObservableList or ObservableMap, respectively. This is a convenience function to make it easier to convert literals into the corresponding observable collection type.

Classes

ChangeNotifier

Interface representing an Observable object that performs its own change notifications, and does not need to be considered by Observable.dirtyCheck.

ChangeNotifierBase

Base class implementing ChangeNotifier.

ChangeNotifierMixin

Mixin for implementing ChangeNotifier objects.

ChangeRecord

Records a change to an Observable.

CompoundBinding

CompoundBinding is an object which knows how to listen to multiple path values (registered via bind) and invoke its combinator when one or more of the values have changed and set its value property to the return value of the function. When any value has changed, all current values are provided to the combinator in the single values argument.

ListChangeRecord

A change record for an observable list.

MapChangeRecord

Observable

Interface representing an observable object. This is used by data in model-view architectures to notify interested parties of changes.

ObservableBase

Base class implementing Observable.

ObservableBox

An observable box that holds a value. Use this if you want to store a single value. For other cases, it is better to use ObservableList, ObservableMap, or a custom Observable implementation based on ObservableMixin. The property name for changes is "value".

ObservableList

Represents an observable list of model values. If any items are added, removed, or replaced, then observers that are listening to changes will be notified.

ObservableMap

Represents an observable map of model values. If any items are added, removed, or replaced, then observers that are listening to changes will be notified.

ObservableMixin

Mixin for implementing Observable objects.

PathObserver

A data-bound path starting from a view-model or model object, for example foo.bar.baz.

PropertyChangeRecord

A change record to a field of an observable object.