繁体   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