【发布时间】:2018-02-05 22:52:26
【问题描述】:
我正在为属性创建自己的装饰器,它将自动将属性的值与 firebase db 同步。我的装饰器非常简单,看起来像这样:
export function AutoSync(firebasePath: string) {
return (target: any, propertyKey: string) => {
let _propertyValue = target[propertyKey];
// get reference to db
const _ref = firebase.database().ref(firebasePath);
// listen for data from db
_ref.on('value', snapshot => {
_propertyValue = snapshot.val();
});
Object.defineProperty(target, propertyKey, {
get: () => _propertyValue,
set: (v) => {
_propertyValue = v;
_ref.set(v);
},
});
}
}
我是这样使用的:
@AutoSync('/config') configuration;
而且它(几乎)就像一个魅力。我的configuration 属性自动与路径/config 上的firebase db 对象同步。属性设置器会自动更新 db 中的值 - 效果很好!
现在的问题:当数据库中的值被其他应用程序在 firebase db 中更新时,我们得到 snapshow 并且 _propertyValue 的值正在被正确更新,但由于 configuration 属性未更改,因此不会触发 changeDetection直接。
所以我需要手动完成。我正在考虑从装饰器中的函数触发更改检测器,但我不确定如何将更改检测器的实例传递给装饰器。
我有一个解决方法:在app.component 的构造函数中,我保存了对全局窗口对象中更改检测器实例的引用:
constructor(cd: ChangeDetectorRef) {
window['cd'] = cd;
(...)
}
现在我可以像这样在AutoSync 装饰器中使用它:
// listen for data from db
_ref.on('value', snapshot => {
_propertyValue = snapshot.val();
window['cd'].detectChanges();
});
但这是一种老套且肮脏的解决方案。什么是正确的方法?
【问题讨论】:
-
这主要是 TypeScript 问题。
标签: angular typescript dependency-injection angular2-changedetection angular-decorator