Synchronously deliver pending changes
. Returns true if any records were
delivered, otherwise false.
Source
// TODO(jmesserly): this is a bit different from the ES Harmony version, which
// allows delivery of changes to a particular observer:
// http://wiki.ecmascript.org/doku.php?id=harmony:observe#object.deliverchangerecords
//
// The rationale for that, and for async delivery in general, is the principal
// that you shouldn't run code (observers) when it doesn't expect to be run.
// If you do that, you risk violating invariants that the code assumes.
//
// For this reason, we need to match the ES Harmony version. The way we can do
// this in Dart is to add a method on StreamSubscription (possibly by
// subclassing Stream* types) that immediately delivers records for only
// that subscription. Alternatively, we could consider using something other
// than Stream to deliver the multicast change records, and provide an
// Observable->Stream adapter.
//
// Also: we should be delivering changes to the observer (subscription) based
// on the birth order of the observer. This is for compatibility with ES
// Harmony as well as predictability for app developers.
bool deliverChanges() {
if (_values == null || !hasObservers) return false;
// Start with manually notified records (computed properties, etc),
// then scan all fields for additional changes.
List records = _records;
_records = null;
InstanceMirror im = observableObject.reflect(this);
_values.forEach((name, oldValue) {
var newValue = im.invokeGetter(name);
if (oldValue != newValue) {
if (records == null) records = [];
records.add(new PropertyChangeRecord(this, name, oldValue, newValue));
_values[name] = newValue;
}
});
if (records == null) return false;
_changes.add(new UnmodifiableListView<ChangeRecord>(records));
return true;
}