[英]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.