| 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 |