Angular FormGroup patchValue/setValue 不会触发属性装饰器的 getter

问题描述 投票:0回答:1

我正在尝试使用名为

@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 属性?

angular typescript angular-forms
1个回答
0
投票

要了解发生了什么,您需要查看

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
不会为您定义密钥。

© www.soinside.com 2019 - 2024. All rights reserved.