OLD | NEW |
| (Empty) |
1 # observe | |
2 | |
3 Support for marking objects as observable, and getting notifications when those | |
4 objects are mutated. | |
5 | |
6 **Warning:** This library is experimental, and APIs are subject to change. | |
7 | |
8 This library is used to observe changes to [Observable][] types. It also | |
9 has helpers to make implementing and using [Observable][] objects easy. | |
10 | |
11 You can provide an observable object in two ways. The simplest way is to | |
12 use dirty checking to discover changes automatically: | |
13 | |
14 ```dart | |
15 import 'package:observe/observe.dart'; | |
16 import 'package:observe/mirrors_used.dart'; // for smaller code | |
17 | |
18 class Monster extends Unit with Observable { | |
19 @observable int health = 100; | |
20 | |
21 void damage(int amount) { | |
22 print('$this takes $amount damage!'); | |
23 health -= amount; | |
24 } | |
25 | |
26 toString() => 'Monster with $health hit points'; | |
27 } | |
28 | |
29 main() { | |
30 var obj = new Monster(); | |
31 obj.changes.listen((records) { | |
32 print('Changes to $obj were: $records'); | |
33 }); | |
34 // No changes are delivered until we check for them | |
35 obj.damage(10); | |
36 obj.damage(20); | |
37 print('dirty checking!'); | |
38 Observable.dirtyCheck(); | |
39 print('done!'); | |
40 } | |
41 ``` | |
42 | |
43 A more sophisticated approach is to implement the change notification | |
44 manually. This avoids the potentially expensive [Observable.dirtyCheck][] | |
45 operation, but requires more work in the object: | |
46 | |
47 ```dart | |
48 import 'package:observe/observe.dart'; | |
49 import 'package:observe/mirrors_used.dart'; // for smaller code | |
50 | |
51 class Monster extends Unit with ChangeNotifier { | |
52 int _health = 100; | |
53 @reflectable get health => _health; | |
54 @reflectable set health(val) { | |
55 _health = notifyPropertyChange(#health, _health, val); | |
56 } | |
57 | |
58 void damage(int amount) { | |
59 print('$this takes $amount damage!'); | |
60 health -= amount; | |
61 } | |
62 | |
63 toString() => 'Monster with $health hit points'; | |
64 } | |
65 | |
66 main() { | |
67 var obj = new Monster(); | |
68 obj.changes.listen((records) { | |
69 print('Changes to $obj were: $records'); | |
70 }); | |
71 // Schedules asynchronous delivery of these changes | |
72 obj.damage(10); | |
73 obj.damage(20); | |
74 print('done!'); | |
75 } | |
76 ``` | |
77 | |
78 **Note**: by default this package uses mirrors to access getters and setters | |
79 marked with `@reflectable`. Dart2js disables tree-shaking if there are any | |
80 uses of mirrors, unless you declare how mirrors are used (via the | |
81 [MirrorsUsed](https://api.dartlang.org/apidocs/channels/stable/#dart-mirrors.Mir
rorsUsed) | |
82 annotation). | |
83 | |
84 As of version 0.10.0, this package doesn't declare `@MirrorsUsed`. This is | |
85 because we intend to use mirrors for development time, but assume that | |
86 frameworks and apps that use this pacakge will either generate code that | |
87 replaces the use of mirrors, or add the `@MirrorsUsed` declaration | |
88 themselves. For convenience, you can import | |
89 `package:observe/mirrors_used.dart` as shown on the first example above. | |
90 That will add a `@MirrorsUsed` annotation that preserves properties and | |
91 classes labeled with `@reflectable` and properties labeled with | |
92 `@observable`. | |
93 | |
94 If you are using the `package:observe/mirrors_used.dart` import, you can | |
95 also make use of `@reflectable` on your own classes and dart2js will | |
96 preserve all of its members for reflection. | |
97 | |
98 [Tools](https://www.dartlang.org/polymer-dart/) exist to convert the first | |
99 form into the second form automatically, to get the best of both worlds. | |
100 | |
101 [Observable]: http://www.dartdocs.org/documentation/observe/latest/index.html#ob
serve/observe.Observable | |
102 [Observable.dirtyCheck]: http://www.dartdocs.org/documentation/observe/latest/in
dex.html#observe/observe.Observable@id_dirtyCheck | |
OLD | NEW |