@msom/reaction
Version:
@msom/reaction
59 lines (57 loc) • 1.98 kB
text/typescript
import {
ObserverDecoratorUsedError,
defineAccesser,
defineProperty,
initComponentDefinition,
isComponent,
} from "@msom/common";
import { ObserverOption } from "../Observer";
import { _observer, generateIObserver } from "../utils";
export function observer<T>(option: ObserverOption<T> = {}): PropertyDecorator {
return function (target, key) {
// 实例属性target为类的原型对象
// 静态属性target为类构造器
// 非静态
if (typeof target === "function") {
throw new ObserverDecoratorUsedError({ NotStatic: true });
}
const descriptor = Object.getOwnPropertyDescriptor(target, key);
// 原型对象上有key,则表示该属性是访问器属性或方法
if (descriptor) {
// 非方法属性
if (typeof descriptor.value === "function") {
throw new ObserverDecoratorUsedError({ NotMethod: true });
}
// 非访问器属性
throw new ObserverDecoratorUsedError({ NotAccessor: true });
}
if (isComponent(target)) {
// 初始化组件定义
const definition = initComponentDefinition(target);
// 判断是否已经标记为响应式
if (Reflect.has(definition.$observers, key)) {
throw new ObserverDecoratorUsedError({
defineMessage() {
return `the observer property ${String(key)} is exist.`;
},
});
}
// 标记
defineProperty(definition.$observers, key, 7, "observer");
}
// 创建观察者
defineAccesser(
target,
key,
5,
function (this: any) {
// 每个对象实例的监听对象独立构造
return generateIObserver.bind(this)(key, _observer, option).get();
},
function (this: any, value: T) {
// 每个对象实例的监听对象独立构造
return generateIObserver.bind(this)(key, _observer, option).set(value);
}
);
};
}