dart-archive / observe

Support for marking objects as observable, and getting notifications when those objects are mutated
https://pub.dartlang.org/packages/observe
BSD 3-Clause "New" or "Revised" License
13 stars 6 forks source link

Better support map.keys/map.values in bindings #67

Open DartBot opened 9 years ago

DartBot commented 9 years ago

Issue by sigmundch Originally opened as dart-lang/sdk#20211


Right now map.keys/map.values return a new list every time they are requested. This can bring up issues in bindings where we might be comparing object's identities.

One idea is to cache the value and only return a new value when there are changes in the underlying Map. For example, doing something like the following in ObservableMap:

      /// Cache of keys so that only a new collection is created when we have reason       /// to believe the keys have changed.       Iterable<K> _keys;       @­reflectable Iterable<K> get keys {         if (_keys == null) _keys = _map.keys;         return _keys;       }            /// Cache of keys so that only a new collection is created when we have reason       /// to believe the values have changed.       Iterable<V> _values;       @­reflectable Iterable<V> get values {         if (_values == null) _values = _map.values;         return _values;       }            ...            // Note: we don't really have a reasonable old/new value to use here.       // But this should fix "keys" and "values" in templates with minimal overhead.       void _notifyKeysValuesChanged() {         _keys = null;         notifyChange(new PropertyChangeRecord(this, #keys, null, null));         _notifyValuesChanged();       }            void _notifyValuesChanged() {         _values = null;         notifyChange(new PropertyChangeRecord(this, #values, null, null));       }     }  

This unfortunately departs from the semantics we got from dart:core Map, where keys/values are always a new instance.

Other ideas:   - do something similar to the above, but also define observable iterables that can provide notifications for changes in the underlying map.

  - add logic to compare these collections more carefully in the binding layer.

Thoughts?