| 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 /// Support for observing changes in model-view architectures. |
| 6 * Support for observing changes in model-view architectures. | 6 /// |
| 7 * | 7 /// **Warning:** This library is experimental, and APIs are subject to change. |
| 8 * **Warning:** This library is experimental, and APIs are subject to change. | 8 /// |
| 9 * | 9 /// 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 | 10 /// has helpers to make implementing and using [Observable] objects easy. |
| 11 * has helpers to make implementing and using [Observable] objects easy. | 11 /// |
| 12 * | 12 /// 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 | 13 /// use dirty checking to discover changes automatically: |
| 14 * use dirty checking to discover changes automatically: | 14 /// |
| 15 * | 15 /// class Monster extends Unit with Observable { |
| 16 * class Monster extends Unit with Observable { | 16 /// @observable int health = 100; |
| 17 * @observable int health = 100; | 17 /// |
| 18 * | 18 /// void damage(int amount) { |
| 19 * void damage(int amount) { | 19 /// print('$this takes $amount damage!'); |
| 20 * print('$this takes $amount damage!'); | 20 /// health -= amount; |
| 21 * health -= amount; | 21 /// } |
| 22 * } | 22 /// |
| 23 * | 23 /// toString() => 'Monster with $health hit points'; |
| 24 * toString() => 'Monster with $health hit points'; | 24 /// } |
| 25 * } | 25 /// |
| 26 * | 26 /// main() { |
| 27 * main() { | 27 /// var obj = new Monster(); |
| 28 * var obj = new Monster(); | 28 /// obj.changes.listen((records) { |
| 29 * obj.changes.listen((records) { | 29 /// print('Changes to $obj were: $records'); |
| 30 * print('Changes to $obj were: $records'); | 30 /// }); |
| 31 * }); | 31 /// // No changes are delivered until we check for them |
| 32 * // No changes are delivered until we check for them | 32 /// obj.damage(10); |
| 33 * obj.damage(10); | 33 /// obj.damage(20); |
| 34 * obj.damage(20); | 34 /// print('dirty checking!'); |
| 35 * print('dirty checking!'); | 35 /// Observable.dirtyCheck(); |
| 36 * Observable.dirtyCheck(); | 36 /// print('done!'); |
| 37 * print('done!'); | 37 /// } |
| 38 * } | 38 /// |
| 39 * | 39 /// A more sophisticated approach is to implement the change notification |
| 40 * A more sophisticated approach is to implement the change notification | 40 /// manually. This avoids the potentially expensive [Observable.dirtyCheck] |
| 41 * manually. This avoids the potentially expensive [Observable.dirtyCheck] | 41 /// operation, but requires more work in the object: |
| 42 * operation, but requires more work in the object: | 42 /// |
| 43 * | 43 /// class Monster extends Unit with ChangeNotifier { |
| 44 * class Monster extends Unit with ChangeNotifier { | 44 /// int _health = 100; |
| 45 * int _health = 100; | 45 /// @reflectable get health => _health; |
| 46 * @reflectable get health => _health; | 46 /// @reflectable set health(val) { |
| 47 * @reflectable set health(val) { | 47 /// _health = notifyPropertyChange(#health, _health, val); |
| 48 * _health = notifyPropertyChange(#health, _health, val); | 48 /// } |
| 49 * } | 49 /// |
| 50 * | 50 /// void damage(int amount) { |
| 51 * void damage(int amount) { | 51 /// print('$this takes $amount damage!'); |
| 52 * print('$this takes $amount damage!'); | 52 /// health -= amount; |
| 53 * health -= amount; | 53 /// } |
| 54 * } | 54 /// |
| 55 * | 55 /// toString() => 'Monster with $health hit points'; |
| 56 * toString() => 'Monster with $health hit points'; | 56 /// } |
| 57 * } | 57 /// |
| 58 * | 58 /// main() { |
| 59 * main() { | 59 /// var obj = new Monster(); |
| 60 * var obj = new Monster(); | 60 /// obj.changes.listen((records) { |
| 61 * obj.changes.listen((records) { | 61 /// print('Changes to $obj were: $records'); |
| 62 * print('Changes to $obj were: $records'); | 62 /// }); |
| 63 * }); | 63 /// // Schedules asynchronous delivery of these changes |
| 64 * // Schedules asynchronous delivery of these changes | 64 /// obj.damage(10); |
| 65 * obj.damage(10); | 65 /// obj.damage(20); |
| 66 * obj.damage(20); | 66 /// print('done!'); |
| 67 * print('done!'); | 67 /// } |
| 68 * } | 68 /// |
| 69 * | 69 /// *Note*: it is good practice to keep `@reflectable` annotation on |
| 70 * *Note*: it is good practice to keep `@reflectable` annotation on | 70 /// getters/setters so they are accessible via reflection. This will preserve |
| 71 * getters/setters so they are accessible via reflection. This will preserve | 71 /// them from tree-shaking. You can also put this annotation on the class and it |
| 72 * them from tree-shaking. You can also put this annotation on the class and it | 72 /// preserve all of its members for reflection. |
| 73 * preserve all of its members for reflection. | 73 /// |
| 74 * | 74 /// [Tools](https://www.dartlang.org/polymer-dart/) exist to convert the first |
| 75 * [Tools](https://www.dartlang.org/polymer-dart/) exist to convert the first | 75 /// form into the second form automatically, to get the best of both worlds. |
| 76 * form into the second form automatically, to get the best of both worlds. | |
| 77 */ | |
| 78 library observe; | 76 library observe; |
| 79 | 77 |
| 80 // This library contains code ported from observe-js: | 78 // This library contains code ported from observe-js: |
| 81 // https://github.com/Polymer/observe-js/blob/0152d542350239563d0f2cad39d22d3254
bd6c2a/src/observe.js | 79 // https://github.com/Polymer/observe-js/blob/0152d542350239563d0f2cad39d22d3254
bd6c2a/src/observe.js |
| 82 // We port what is needed for data bindings. Most of the functionality is | 80 // We port what is needed for data bindings. Most of the functionality is |
| 83 // ported, except where differences are needed for Dart's Observable type. | 81 // ported, except where differences are needed for Dart's Observable type. |
| 84 | 82 |
| 85 export 'src/bindable.dart'; | 83 export 'src/bindable.dart'; |
| 86 export 'src/bind_property.dart'; | 84 export 'src/bind_property.dart'; |
| 87 export 'src/change_notifier.dart'; | 85 export 'src/change_notifier.dart'; |
| 88 export 'src/change_record.dart'; | 86 export 'src/change_record.dart'; |
| 89 export 'src/list_path_observer.dart'; | 87 export 'src/list_path_observer.dart'; |
| 90 export 'src/list_diff.dart' show ListChangeRecord; | 88 export 'src/list_diff.dart' show ListChangeRecord; |
| 91 export 'src/metadata.dart'; | 89 export 'src/metadata.dart'; |
| 92 export 'src/observable.dart' hide notifyPropertyChangeHelper, objectType; | 90 export 'src/observable.dart' hide notifyPropertyChangeHelper, objectType; |
| 93 export 'src/observable_box.dart'; | 91 export 'src/observable_box.dart'; |
| 94 export 'src/observable_list.dart'; | 92 export 'src/observable_list.dart'; |
| 95 export 'src/observable_map.dart'; | 93 export 'src/observable_map.dart'; |
| 96 export 'src/observer_transform.dart'; | 94 export 'src/observer_transform.dart'; |
| 97 export 'src/path_observer.dart'; | 95 export 'src/path_observer.dart'; |
| 98 export 'src/to_observable.dart'; | 96 export 'src/to_observable.dart'; |
| OLD | NEW |