我正在尝试使用名为
@Amount()
的自定义属性装饰器,它最终会将属性值格式化为我需要的特定格式。
amount.decorator.ts
export const Amount = () =>
(target: any, key: string) => {
let _value: number | string = target[key];
if (delete target[key]) {
return Object.defineProperty(target, key, {
configurable: false,
enumerable: true,
get: () => {
console.log("returning", "$" + _value);
return "$" + _value;
},
set: (val) => {
console.log("setting val", val);
_value = val;
},
});
}
}
summary.model.ts
export class Summary {
regularField!: string;
@Amount() amountField!: number | string;
}
form.component.ts
export class SummaryComponent implements OnInit {
summary: Summary;
form: FormGroup = new FormGroup({
regularField: new FormControl(''),
amountField: new FormControl('Initial value'),
});
ngOnInit() {
this.summary = this.service.getSummary();
// summary.regularField is "Hello world!"
// summary.amountField is 123.00
this.summary.amountField = 456.00; <-- triggers "setting val" comment as expected
console.log(this.summary.amountField); <-- triggers "returning" comment from @Amount() as expected
console.log(this.form.controls['amountField'].value); <-- shows "Initial value"
this.form.patchValue(this.summary || {}); <-- expectation is the getter is called in order to patch it to the formcontrol, but it is not is called
console.log(this.form.controls['amountField'].value); <-- still shows "Initial value"
}
}
是否有我遗漏的东西,或者我误解了 patchValue 的一些内部逻辑,导致它无法检索 amountField 属性?
要了解发生了什么,您需要查看
patchvalue
/setValue()
的实现:
(Object.keys(value) as Array<keyof TControl>).forEach(name => {
assertControlPresent(this, true, name as any);
(this.controls as any)[name].setValue(
(value as any)[name], {onlySelf: true, emitEvent: options.emitEvent});
});
如您所见,它迭代
value
的键来更新控件。
此问题是您正在删除
decorator with delete target[key]
中的密钥。 Object.defineProperty
不会为您定义密钥。