OLD | NEW |
| (Empty) |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library observe.src.list_path_observer; | |
6 | |
7 import 'dart:async'; | |
8 import 'package:observe/observe.dart'; | |
9 | |
10 // Inspired by ArrayReduction at: | |
11 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js | |
12 // The main difference is we support anything on the rich Dart Iterable API. | |
13 | |
14 /// Observes a path starting from each item in the list. | |
15 @deprecated | |
16 class ListPathObserver<E, P> extends ChangeNotifier { | |
17 final ObservableList<E> list; | |
18 final String _itemPath; | |
19 final List<PathObserver> _observers = <PathObserver>[]; | |
20 StreamSubscription _sub; | |
21 bool _scheduled = false; | |
22 Iterable<P> _value; | |
23 | |
24 ListPathObserver(this.list, String path) | |
25 : _itemPath = path { | |
26 | |
27 // TODO(jmesserly): delay observation until we are observed. | |
28 _sub = list.listChanges.listen((records) { | |
29 for (var record in records) { | |
30 _observeItems(record.addedCount - record.removed.length); | |
31 } | |
32 _scheduleReduce(null); | |
33 }); | |
34 | |
35 _observeItems(list.length); | |
36 _reduce(); | |
37 } | |
38 | |
39 @reflectable Iterable<P> get value => _value; | |
40 | |
41 void dispose() { | |
42 if (_sub != null) _sub.cancel(); | |
43 _observers.forEach((o) => o.close()); | |
44 _observers.clear(); | |
45 } | |
46 | |
47 void _reduce() { | |
48 _scheduled = false; | |
49 var newValue = _observers.map((o) => o.value); | |
50 _value = notifyPropertyChange(#value, _value, newValue); | |
51 } | |
52 | |
53 void _scheduleReduce(_) { | |
54 if (_scheduled) return; | |
55 _scheduled = true; | |
56 scheduleMicrotask(_reduce); | |
57 } | |
58 | |
59 void _observeItems(int lengthAdjust) { | |
60 if (lengthAdjust > 0) { | |
61 for (int i = 0; i < lengthAdjust; i++) { | |
62 int len = _observers.length; | |
63 var pathObs = new PathObserver(list, '[$len].$_itemPath'); | |
64 pathObs.open(_scheduleReduce); | |
65 _observers.add(pathObs); | |
66 } | |
67 } else if (lengthAdjust < 0) { | |
68 for (int i = 0; i < -lengthAdjust; i++) { | |
69 _observers.removeLast().close(); | |
70 } | |
71 } | |
72 } | |
73 } | |
OLD | NEW |