Skip to content

Commit

Permalink
feat: add observable decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
wewoor committed Oct 31, 2020
1 parent 4b9582a commit e54aa51
Showing 1 changed file with 51 additions and 6 deletions.
57 changes: 51 additions & 6 deletions src/common/observable.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
export interface IObservable {
observe: (handler: (target, property, value) => void) => void;
/**
* The onChange of observed object
*/
observe: (onChange: (target, property, value) => void) => void;
}

export function observable<T>(object, callback?): IObservable & T {
object.handlers = [];
object.observe = function(handler: Function) {
object.handlers.push(handler);
};
/**
* Wrap an object to an observable object
* @param object target object
* @param callback callback when target observed
*/
export function observableWrapper<T>(object, callback?): IObservable & T {
Object.setPrototypeOf(object, {
handlers: [],
observe: function(onChange: Function) {
object.handlers.push(onChange);
},
});

const handler = {
get(target, property, receiver) {
Expand Down Expand Up @@ -42,3 +52,38 @@ export function observable<T>(object, callback?): IObservable & T {
};
return new Proxy(object, handler);
}

/**
* Observable decorator
* @param target observable target object
* @param name
* @param descriptor
*/
export function observable(): any {
return function(
target,
property: string,
descriptor: PropertyDescriptor,
) {
try {
const Original = target;

const decoratedConstructor = function(...args: any[]): void {
const Obj: any = function() {
return new Original(args);
};

Obj.prototype = Original.prototype;
const result = new Obj();

return observableWrapper(result);
};

decoratedConstructor.prototype = Original.prototype;
return decoratedConstructor;
} catch (e) {
console.error('observable error:', e);
return target;
}
};
}

0 comments on commit e54aa51

Please sign in to comment.