typescript - 如何使用类型检查设置对象属性,但在更改时触发函数
问题描述
我有一个看起来像这样的类:
export class Settings {
public controls: SettingControls {
toolbarOpen: false,
awaitingHttpResponse: false,
selectedTab: TabOption.NOTIFICATIONS,
selectedTheme: ThemeOption.DARK
// etc. (the actual amount of controls is much longer)
};
}
我想检测何时对controls
属性进行更改并用可观察的方式宣布它。目前我用一个简单的setControl
函数来做(并将_controls
属性设置为私有):
setControl(key, value) {
this._controls[key] = value;
this._updatedSetting.next({key, value}); // Announce the change
}
这有效,但这意味着没有检查值的类型。我已经研究过动态生成 getter 和 setter(像这样),但不幸的是,这并没有帮助。我可以为每个属性分别写出一个 getter/setting,但我想避免这种情况。
解决方案
您可以通过安装访问器(getter/setter)来做到这一点,正如您已经说过的。当您尝试为控件对象(具有 SettingsControl 类型)的属性分配值时,将执行 typescript 的类型检查。看看下面的代码,当一个值被分配给控件对象的任何属性并进行类型检查时,它会调用 fireControlUpdated。
请注意,您应该在每次添加/删除控件对象的属性时调用 installAccessors() 以使其正常工作。
enum ENUM1 {
val1,
val2,
}
enum ENUM2 {
val1,
val2,
}
interface SettingsControls {
toolbarOpen: boolean,
awaitingHttpResponse: boolean,
selectedTab: ENUM1,
selectedTheme: ENUM2
}
class Settings {
private _controls = {};
public controls: SettingsControls = {
toolbarOpen: false,
awaitingHttpResponse: false,
selectedTab: ENUM1.val2,
selectedTheme: ENUM2.val1
};
constructor() {
this.installAccessors();
}
installAccessors() {
for (let key in this.controls) {
if (this.controls.hasOwnProperty(key)) {
Object.defineProperty(this.controls, key, {
get: () => { return this._controls[key]; },
set: (v: any) => {
console.log(this);
this._controls[key] = v;
this.fireControlUpdated(key, v);
}
});
}
}
}
fireControlUpdated(key: string, v: any) {
console.log(`key ${key}: new value: ${v}`)
}
}
let a = new Settings();
a.controls.toolbarOpen = true;
// the following will produce typescript compile error because
// the type of the selectedTab is ENUM1
// a.controls.selectedTab = ENUM2.val1;
// this one works
a.controls.selectedTab = ENUM1.val2;
console.log("toolbarOpen is: " + a.controls.toolbarOpen);
console.log("selectedTab is: " + ENUM1[a.controls.selectedTab]);
推荐阅读
- wordpress - 将 get_results 添加到 WordPress REST API
- c# - 在 Windows 服务器上从 C# 运行 Powershell 脚本
- angular - 如何以角度有条件地触发验证检查
- java - 模棱两可的方法调用 println char 数组和 String(而不是 Object)
- excel - 日期从周数和工作日名称
- css - Canvas (Chart.js) 在 Chrome 上正确调整大小,而在 Safari 上它甚至不显示
- roku - Roku 中的全局数组访问
- r - 从新结果中减去
- c# - EF Core 和 CosmosDB 提供程序的自有集合异常
- ruby-on-rails - 生产中表单字段中的操作文本错误 [Heroku + Rails 6]