|
1 | 1 | export interface IObservable {
|
2 |
| - observe: (handler: (target, property, value) => void) => void; |
| 2 | + /** |
| 3 | + * The onChange of observed object |
| 4 | + */ |
| 5 | + observe: (onChange: (target, property, value) => void) => void; |
3 | 6 | }
|
4 | 7 |
|
5 |
| -export function observable<T>(object, callback?): IObservable & T { |
6 |
| - object.handlers = []; |
7 |
| - object.observe = function(handler: Function) { |
8 |
| - object.handlers.push(handler); |
9 |
| - }; |
| 8 | +/** |
| 9 | + * Wrap an object to an observable object |
| 10 | + * @param object target object |
| 11 | + * @param callback callback when target observed |
| 12 | + */ |
| 13 | +export function observableWrapper<T>(object, callback?): IObservable & T { |
| 14 | + Object.setPrototypeOf(object, { |
| 15 | + handlers: [], |
| 16 | + observe: function(onChange: Function) { |
| 17 | + object.handlers.push(onChange); |
| 18 | + }, |
| 19 | + }); |
10 | 20 |
|
11 | 21 | const handler = {
|
12 | 22 | get(target, property, receiver) {
|
@@ -42,3 +52,38 @@ export function observable<T>(object, callback?): IObservable & T {
|
42 | 52 | };
|
43 | 53 | return new Proxy(object, handler);
|
44 | 54 | }
|
| 55 | + |
| 56 | +/** |
| 57 | + * Observable decorator |
| 58 | + * @param target observable target object |
| 59 | + * @param name |
| 60 | + * @param descriptor |
| 61 | + */ |
| 62 | +export function observable(): any { |
| 63 | + return function( |
| 64 | + target, |
| 65 | + property: string, |
| 66 | + descriptor: PropertyDescriptor, |
| 67 | + ) { |
| 68 | + try { |
| 69 | + const Original = target; |
| 70 | + |
| 71 | + const decoratedConstructor = function(...args: any[]): void { |
| 72 | + const Obj: any = function() { |
| 73 | + return new Original(args); |
| 74 | + }; |
| 75 | + |
| 76 | + Obj.prototype = Original.prototype; |
| 77 | + const result = new Obj(); |
| 78 | + |
| 79 | + return observableWrapper(result); |
| 80 | + }; |
| 81 | + |
| 82 | + decoratedConstructor.prototype = Original.prototype; |
| 83 | + return decoratedConstructor; |
| 84 | + } catch (e) { |
| 85 | + console.error('observable error:', e); |
| 86 | + return target; |
| 87 | + } |
| 88 | + }; |
| 89 | +} |
0 commit comments