简体   繁体   English

Typescript:反应性 forms patchValue 不适用于私有属性和 getter/setter

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

I'm using an Angular/.net application with .net6.0 framework, with Angular: 13.1.2, Node: 16.13.1 and EMCAScript 5.我正在使用带有 .net6.0 框架的 Angular/.net 应用程序,Angular:13.1.2,节点:16.13.1 和 EMCAScript 5。

I have the following person class in typescript.我在 typescript 中有以下人 class。

export class Person {

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

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

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

While compiling the following person.model.js file is generated.编译时生成以下 person.model.js 文件。 But I'm under the impression the Object.defineProperties doesn't work.但我的印象是 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

Whenever I try to update my Reactive form using an object no data is updated.每当我尝试使用 object 更新我的 Reactive 表单时,都不会更新任何数据。 While I'm debugging I only notice the '_name' property in the 'Object.Keys' array.在调试时,我只注意到“Object.Keys”数组中的“_name”属性。

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

Reactive form is defined the following way.反应形式定义如下。

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

Whenever I update my class with 'Object.DefineProperty' the above code updating the Reactive form seems to work without problems.每当我用“Object.DefineProperty”更新我的 class 时,上面更新反应形式的代码似乎没有问题。 Also the 'Name' property seems to have been added to the 'Object.Keys' array.此外,“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
    })
  }
}

Do I need to add the Object.defineProperties in the.ts file or is my application not using the generated.js files?我需要在 .ts 文件中添加 Object.defineProperties 还是我的应用程序没有使用 generated.js 文件?

EDIT:编辑:

Component零件

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: 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 does transpiles the getter/setter into an equivalent Object.defineProperty syntax. TypeScript 确实将 getter/setter 转换为等效的Object.defineProperty语法。

But if you carefully look at the transpiled code, you will observe that the name property is defined on Person.prototype ie on function's prototype, and not on the function itself.但是如果您仔细查看转译的代码,您会发现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;
}());

Whereas in the 2nd scenario, wherein you manually define Object.defineProperty , you are passing 1st argument as this , and not Person.prototype.而在第二种情况下,您手动定义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;
}());

This is the reason why name property is not visible within Object.keys in 1st scenario (getter/setter), but is visible in the 2nd scenario.这就是为什么name属性在第一种情况(getter/setter)中在Object.keys中不可见,但在第二种情况下可见的原因。 And for the same reason the patchValue doesn't work as name is not an object's own enumerable property.出于同样的原因, patchValue不起作用,因为name不是对象自己的可枚举属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 反应形式 patchValue() 与 ngValue 不起作用 - Reactive forms patchValue() with ngValue not working Angular 反应式 Forms,patchValue 不起作用,嵌套 forms - Angular Reactive Forms, patchValue not working, nested forms For 循环中的反应形式 patchValue() - Reactive Forms patchValue() in For loop Angular 反应形式 patchValue 或 setValue 不起作用 - Angular 10 - Angular reactive forms patchValue or setValue not working - Angular 10 将 Angular 中共享服务的属性用作 getter 和 setter 的私有属性的原因是什么? - What is a reason to use properties of shared service in Angular as private with getters and setters? 如何使用setter和getter在TypeScript中正确设置对象属性? - How to properly set object properties in TypeScript with setters and getters? 在具有父子路由的Reactive Forms中使用patchValue - Use Of patchValue in Reactive Forms with parent child routing Angular 5 反应形式 - 带有 FormArray 的 patchValue 不起作用 - Angular 5 reactive form - patchValue with FormArray not working 打字稿:类成员初始化与 setter 和 getter - Typescript: Class members initialization vs setters and getters 如何在测试角度2反应形式中使用setValue和patchValue - How to use setValue and patchValue in testing angular 2 reactive forms
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM