簡體   English   中英

Typescript:反應性 forms patchValue 不適用於私有屬性和 getter/setter

[英]Typescript: Reactive forms patchValue not working with private properties and getters/setters

我正在使用帶有 .net6.0 框架的 Angular/.net 應用程序,Angular:13.1.2,節點:16.13.1 和 EMCAScript 5。

我在 typescript 中有以下人 class。

export class Person {

  private _name: string = '';
    
  constructor() {
  }

  public get name(): string {
    return this._name;
  }

  public set name(value: string) {
    this._name = value;
  }
}

編譯時生成以下 person.model.js 文件。 但我的印象是 Object.defineProperties 不起作用。

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Person = /** @class */ (function () {
    function Person() {
        this._name = '';
    }
    Object.defineProperty(Person.prototype, "name", {
        get: function () {
            return this._name;
        },
        set: function (value) {
            this._name = value;
        },
        enumerable: true,
        configurable: true
    });
    return Person;
}());
exports.Person = Person;
//# sourceMappingURL=person.model.js.map

每當我嘗試使用 object 更新我的 Reactive 表單時,都不會更新任何數據。 在調試時,我只注意到“Object.Keys”數組中的“_name”屬性。

 this.personForm.get('person')?.patchValue(person);

反應形式定義如下。

    return formBuilder.group({
      person: formBuilder.group({
        name: [
          '',
          [
            Validators.required
          ]
        ]
      })
    });

每當我用“Object.DefineProperty”更新我的 class 時,上面更新反應形式的代碼似乎沒有問題。 此外,“Name”屬性似乎已添加到“Object.Keys”數組中。

export class Person {

  private _name: string = '';
    
  constructor() {
    Object.defineProperty(this, 'name', {
      set: function (value: string) {
        this._name = value;
      },
      get: function () {
        return this._name;
      },
      enumerable: true
    })
  }
}

我需要在 .ts 文件中添加 Object.defineProperties 還是我的應用程序沒有使用 generated.js 文件?

編輯:

零件

export class PersonComponent implements OnInit {

  personForm!: FormGroup;

  constructor(
    private _fb: FormBuilder) {}

  private CreateFormGroup(formBuilder: FormBuilder): FormGroup {
    return formBuilder.group({
      person: formBuilder.group({
        name: [
          '',
          [
            Validators.required
          ]
        ]
      })
    });
  }

  ngOnInit(): void {
    this.personForm = this.CreateFormGroup(this._fb);
  }

  setPerson(person: Person) {
    if (person != undefined) {
      this.personForm.get('person')?.patchValue(person);
    }
  }

}

HTML:

<mat-card class="mat-elevation-z10">
  <mat-card-title>Person</mat-card-title>
  <mat-card-content>
    <form [formGroup]="personForm">
      <div formGroupName="person">
        <mat-form-field class="person-name">
          <input id="name" matInput aria-label="name" type="text" formControlName="name" autofocus required />
          <mat-placeholder class="placeholder">name</mat-placeholder>
        </mat-form-field>
      </div>
      <br />
    </form>
  </mat-card-content>
</mat-card>
<app-person-selection (personEvent)="setPerson($event)"></app-person-selection>

TypeScript 確實將 getter/setter 轉換為等效的Object.defineProperty語法。

但是如果您仔細查看轉譯的代碼,您會發現name屬性是在Person.prototype上定義的,即在函數的原型上,而不是在 function 本身上。

// Transpiled code with v3.9.7
var Person = /** @class */ (function () {
    function Person() {
        this._name = '';
    }
    Object.defineProperty(Person.prototype, "name", {  // <----
        get: function () {
            return this._name;
        },
        set: function (value) {
            this._name = value;
        },
        enumerable: false,
        configurable: true
    });
    return Person;
}());

而在第二種情況下,您手動定義Object.defineProperty ,您將第一個參數作為this傳遞,而不是 Person.prototype。

// Transpiled code with v3.9.7
var Person = /** @class */ (function () {
    function Person() {
        this._name = '';
        Object.defineProperty(this, 'name', {  // <----
            set: function (value) {
                this._name = value;
            },
            get: function () {
                return this._name;
            },
            enumerable: true
        });
    }
    return Person;
}());

這就是為什么name屬性在第一種情況(getter/setter)中在Object.keys中不可見,但在第二種情況下可見的原因。 出於同樣的原因, patchValue不起作用,因為name不是對象自己的可枚舉屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM