OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Helpers for observable objects. | 6 * Helpers for observable objects. |
7 * Intended for use with `package:mdv_observe`. | 7 * Intended for use with `package:observe`. |
8 */ | 8 */ |
9 library polymer.observe; | 9 library polymer.observe; |
10 | 10 |
11 import 'dart:async'; | 11 import 'dart:async'; |
12 // TODO(jmesserly): PathObserver should be in mdv_observe. | |
13 import 'dart:html' show PathObserver; | |
14 import 'package:observe/observe.dart'; | 12 import 'package:observe/observe.dart'; |
15 | 13 |
16 // Inspired by ArrayReduction at: | |
17 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js | |
18 // The main difference is we support anything on the rich Dart Iterable API. | |
19 | |
20 const _VALUE = const Symbol('value'); | 14 const _VALUE = const Symbol('value'); |
21 | 15 |
22 /** | 16 /** |
23 * Forwards an observable property from one object to another. For example: | 17 * Forwards an observable property from one object to another. For example: |
24 * | 18 * |
25 * class MyModel extends ObservableBase { | 19 * class MyModel extends ObservableBase { |
26 * StreamSubscription _sub; | 20 * StreamSubscription _sub; |
27 * MyOtherModel _otherModel; | 21 * MyOtherModel _otherModel; |
28 * | 22 * |
29 * MyModel() { | 23 * MyModel() { |
(...skipping 22 matching lines...) Expand all Loading... |
52 /** | 46 /** |
53 * Notify the property change. Shorthand for: | 47 * Notify the property change. Shorthand for: |
54 * | 48 * |
55 * target.notifyChange(new PropertyChangeRecord(targetName)); | 49 * target.notifyChange(new PropertyChangeRecord(targetName)); |
56 */ | 50 */ |
57 void notifyProperty(Observable target, Symbol targetName) { | 51 void notifyProperty(Observable target, Symbol targetName) { |
58 target.notifyChange(new PropertyChangeRecord(targetName)); | 52 target.notifyChange(new PropertyChangeRecord(targetName)); |
59 } | 53 } |
60 | 54 |
61 | 55 |
| 56 // Inspired by ArrayReduction at: |
| 57 // https://raw.github.com/rafaelw/ChangeSummary/master/util/array_reduction.js |
| 58 // The main difference is we support anything on the rich Dart Iterable API. |
| 59 |
62 /** | 60 /** |
63 * Observes a path starting from each item in the list. | 61 * Observes a path starting from each item in the list. |
64 */ | 62 */ |
65 class ListPathObserver<E, P> extends ChangeNotifierBase { | 63 class ListPathObserver<E, P> extends ChangeNotifierBase { |
66 final ObservableList<E> list; | 64 final ObservableList<E> list; |
67 final String _itemPath; | 65 final String _itemPath; |
68 final List<PathObserver> _observers = <PathObserver>[]; | 66 final List<PathObserver> _observers = <PathObserver>[]; |
69 final List<StreamSubscription> _subs = <StreamSubscription>[]; | 67 final List<StreamSubscription> _subs = <StreamSubscription>[]; |
70 StreamSubscription _sub; | 68 StreamSubscription _sub; |
71 bool _scheduled = false; | 69 bool _scheduled = false; |
(...skipping 28 matching lines...) Expand all Loading... |
100 _value = _observers.map((o) => o.value); | 98 _value = _observers.map((o) => o.value); |
101 notifyChange(new PropertyChangeRecord(_VALUE)); | 99 notifyChange(new PropertyChangeRecord(_VALUE)); |
102 } | 100 } |
103 | 101 |
104 void _scheduleReduce(_) { | 102 void _scheduleReduce(_) { |
105 if (_scheduled) return; | 103 if (_scheduled) return; |
106 _scheduled = true; | 104 _scheduled = true; |
107 runAsync(_reduce); | 105 runAsync(_reduce); |
108 } | 106 } |
109 | 107 |
110 _observeItems(int lengthAdjust) { | 108 void _observeItems(int lengthAdjust) { |
111 if (lengthAdjust > 0) { | 109 if (lengthAdjust > 0) { |
112 for (int i = 0; i < lengthAdjust; i++) { | 110 for (int i = 0; i < lengthAdjust; i++) { |
113 int len = _observers.length; | 111 int len = _observers.length; |
114 var pathObs = new PathObserver(list, '$len.$_itemPath'); | 112 var pathObs = new PathObserver(list, '$len.$_itemPath'); |
115 _subs.add(pathObs.changes.listen(_scheduleReduce)); | 113 _subs.add(pathObs.changes.listen(_scheduleReduce)); |
116 _observers.add(pathObs); | 114 _observers.add(pathObs); |
117 } | 115 } |
118 } else if (lengthAdjust < 0) { | 116 } else if (lengthAdjust < 0) { |
119 for (int i = 0; i < -lengthAdjust; i++) { | 117 for (int i = 0; i < -lengthAdjust; i++) { |
120 _subs.removeLast().cancel(); | 118 _subs.removeLast().cancel(); |
121 } | 119 } |
122 int len = _observers.length; | 120 int len = _observers.length; |
123 _observers.removeRange(len + lengthAdjust, len); | 121 _observers.removeRange(len + lengthAdjust, len); |
124 } | 122 } |
125 } | 123 } |
126 } | 124 } |
OLD | NEW |