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 * Support for observing changes in model-view architectures. | 6 * Support for observing changes in model-view architectures. |
7 * | 7 * |
8 * **Warning:** This library is experimental, and APIs are subject to change. | 8 * **Warning:** This library is experimental, and APIs are subject to change. |
9 * | 9 * |
10 * This library is used to observe changes to [Observable] types. It also | 10 * This library is used to observe changes to [Observable] types. It also |
11 * has helpers to make implementing and using [Observable] objects easy. | 11 * has helpers to make implementing and using [Observable] objects easy. |
12 * | 12 * |
13 * You can provide an observable object in two ways. The simplest way is to | 13 * You can provide an observable object in two ways. The simplest way is to |
14 * use dirty checking to discover changes automatically: | 14 * use dirty checking to discover changes automatically: |
15 * | 15 * |
16 * class Monster extends Unit with ObservableMixin { | 16 * class Monster extends Unit with Observable { |
17 * @observable int health = 100; | 17 * @observable int health = 100; |
18 * | 18 * |
19 * void damage(int amount) { | 19 * void damage(int amount) { |
20 * print('$this takes $amount damage!'); | 20 * print('$this takes $amount damage!'); |
21 * health -= amount; | 21 * health -= amount; |
22 * } | 22 * } |
23 * | 23 * |
24 * toString() => 'Monster with $health hit points'; | 24 * toString() => 'Monster with $health hit points'; |
25 * } | 25 * } |
26 * | 26 * |
27 * main() { | 27 * main() { |
28 * var obj = new Monster(); | 28 * var obj = new Monster(); |
29 * obj.changes.listen((records) { | 29 * obj.changes.listen((records) { |
30 * print('Changes to $obj were: $records'); | 30 * print('Changes to $obj were: $records'); |
31 * }); | 31 * }); |
32 * // No changes are delivered until we check for them | 32 * // No changes are delivered until we check for them |
33 * obj.damage(10); | 33 * obj.damage(10); |
34 * obj.damage(20); | 34 * obj.damage(20); |
35 * print('dirty checking!'); | 35 * print('dirty checking!'); |
36 * Observable.dirtyCheck(); | 36 * Observable.dirtyCheck(); |
37 * print('done!'); | 37 * print('done!'); |
38 * } | 38 * } |
39 * | 39 * |
40 * A more sophisticated approach is to implement the change notification | 40 * A more sophisticated approach is to implement the change notification |
41 * manually. This avoids the potentially expensive [Observable.dirtyCheck] | 41 * manually. This avoids the potentially expensive [Observable.dirtyCheck] |
42 * operation, but requires more work in the object: | 42 * operation, but requires more work in the object: |
43 * | 43 * |
44 * class Monster extends Unit with ChangeNotifierMixin { | 44 * class Monster extends Unit with ChangeNotifier { |
45 * int _health = 100; | 45 * int _health = 100; |
46 * @reflectable get health => _health; | 46 * @reflectable get health => _health; |
47 * @reflectable set health(val) { | 47 * @reflectable set health(val) { |
48 * _health = notifyPropertyChange(#health, _health, val); | 48 * _health = notifyPropertyChange(#health, _health, val); |
49 * } | 49 * } |
50 * | 50 * |
51 * void damage(int amount) { | 51 * void damage(int amount) { |
52 * print('$this takes $amount damage!'); | 52 * print('$this takes $amount damage!'); |
53 * health -= amount; | 53 * health -= amount; |
54 * } | 54 * } |
(...skipping 26 matching lines...) Expand all Loading... |
81 import 'dart:collection'; | 81 import 'dart:collection'; |
82 | 82 |
83 // Note: ObservableProperty is in this list only for the unusual use case of | 83 // Note: ObservableProperty is in this list only for the unusual use case of |
84 // dart2js without deploy tool. The deploy tool (see "transformer.dart") will | 84 // dart2js without deploy tool. The deploy tool (see "transformer.dart") will |
85 // add the @reflectable annotation, which makes it work with Polymer's | 85 // add the @reflectable annotation, which makes it work with Polymer's |
86 // @published. | 86 // @published. |
87 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty], | 87 @MirrorsUsed(metaTargets: const [Reflectable, ObservableProperty], |
88 override: 'observe') | 88 override: 'observe') |
89 import 'dart:mirrors'; | 89 import 'dart:mirrors'; |
90 | 90 |
| 91 import 'package:meta/meta.dart'; |
| 92 |
91 // Note: this is an internal library so we can import it from tests. | 93 // Note: this is an internal library so we can import it from tests. |
92 // TODO(jmesserly): ideally we could import this with a prefix, but it caused | 94 // TODO(jmesserly): ideally we could import this with a prefix, but it caused |
93 // strange problems on the VM when I tested out the dirty-checking example | 95 // strange problems on the VM when I tested out the dirty-checking example |
94 // above. | 96 // above. |
95 import 'src/dirty_check.dart'; | 97 import 'src/dirty_check.dart'; |
96 | 98 |
97 part 'src/bind_property.dart'; | 99 part 'src/bind_property.dart'; |
98 part 'src/change_notifier.dart'; | 100 part 'src/change_notifier.dart'; |
99 part 'src/change_record.dart'; | 101 part 'src/change_record.dart'; |
100 part 'src/compound_binding.dart'; | 102 part 'src/compound_binding.dart'; |
101 part 'src/list_path_observer.dart'; | 103 part 'src/list_path_observer.dart'; |
102 part 'src/metadata.dart'; | 104 part 'src/metadata.dart'; |
103 part 'src/observable.dart'; | 105 part 'src/observable.dart'; |
104 part 'src/observable_box.dart'; | 106 part 'src/observable_box.dart'; |
105 part 'src/observable_list.dart'; | 107 part 'src/observable_list.dart'; |
106 part 'src/observable_map.dart'; | 108 part 'src/observable_map.dart'; |
107 part 'src/path_observer.dart'; | 109 part 'src/path_observer.dart'; |
108 part 'src/to_observable.dart'; | 110 part 'src/to_observable.dart'; |
OLD | NEW |