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