| Index: observatory_pub_packages/observe/src/list_path_observer.dart
|
| ===================================================================
|
| --- observatory_pub_packages/observe/src/list_path_observer.dart (revision 0)
|
| +++ observatory_pub_packages/observe/src/list_path_observer.dart (working copy)
|
| @@ -0,0 +1,73 @@
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library observe.src.list_path_observer;
|
| +
|
| +import 'dart:async';
|
| +import 'package:observe/observe.dart';
|
| +
|
| +// Inspired by ArrayReduction at:
|
| +// https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js
|
| +// The main difference is we support anything on the rich Dart Iterable API.
|
| +
|
| +/// Observes a path starting from each item in the list.
|
| +@deprecated
|
| +class ListPathObserver<E, P> extends ChangeNotifier {
|
| + final ObservableList<E> list;
|
| + final String _itemPath;
|
| + final List<PathObserver> _observers = <PathObserver>[];
|
| + StreamSubscription _sub;
|
| + bool _scheduled = false;
|
| + Iterable<P> _value;
|
| +
|
| + ListPathObserver(this.list, String path)
|
| + : _itemPath = path {
|
| +
|
| + // TODO(jmesserly): delay observation until we are observed.
|
| + _sub = list.listChanges.listen((records) {
|
| + for (var record in records) {
|
| + _observeItems(record.addedCount - record.removed.length);
|
| + }
|
| + _scheduleReduce(null);
|
| + });
|
| +
|
| + _observeItems(list.length);
|
| + _reduce();
|
| + }
|
| +
|
| + @reflectable Iterable<P> get value => _value;
|
| +
|
| + void dispose() {
|
| + if (_sub != null) _sub.cancel();
|
| + _observers.forEach((o) => o.close());
|
| + _observers.clear();
|
| + }
|
| +
|
| + void _reduce() {
|
| + _scheduled = false;
|
| + var newValue = _observers.map((o) => o.value);
|
| + _value = notifyPropertyChange(#value, _value, newValue);
|
| + }
|
| +
|
| + void _scheduleReduce(_) {
|
| + if (_scheduled) return;
|
| + _scheduled = true;
|
| + scheduleMicrotask(_reduce);
|
| + }
|
| +
|
| + void _observeItems(int lengthAdjust) {
|
| + if (lengthAdjust > 0) {
|
| + for (int i = 0; i < lengthAdjust; i++) {
|
| + int len = _observers.length;
|
| + var pathObs = new PathObserver(list, '[$len].$_itemPath');
|
| + pathObs.open(_scheduleReduce);
|
| + _observers.add(pathObs);
|
| + }
|
| + } else if (lengthAdjust < 0) {
|
| + for (int i = 0; i < -lengthAdjust; i++) {
|
| + _observers.removeLast().close();
|
| + }
|
| + }
|
| + }
|
| +}
|
|
|