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