我一直在尝试使用我订阅的可观察对象来初始化我的反应式表单。在表单类模板中,我使用 ngOnInit 钩子来获取我想要的对象,在本例中为产品对象。
第一个代码是类模板,第二个代码是 html 模板,我在其中使用行为主题传递产品。
然后,我会收到错误“属性‘产品’在初始化之前被使用。”在表单控件名称实例的第一行。我认为这是因为产品表单是在 ngOnInit 挂钩之前创建的,因此它无法访问该对象。有任何想法吗?被困在这里这么久了,将不胜感激任何帮助!
产品表单组件.ts:
export class ProductFormComponent {
productReceived: Subscription;
editMode: boolean = false;
product: product;
constructor(private productService: ProductService) { }
ngOnInit() {
this.productReceived = this.productService.$emitProduct.subscribe((product: product) => {
if (product) {
this.product = product;
this.editMode = true;
}
});
}
productForm = new FormGroup({
name: new FormControl(`${this.product}`, [Validators.required, Validators.minLength(3)]), // THIS LINE
description: new FormControl(''),
specification: new FormControl(''),
price: new FormControl(''),
imagePath: new FormControl(''),
warranty: new FormControl(''),
});
ngOnDestroy() {
this.productReceived.unsubscribe();
}
}
product-item.component.html:
<div style="cursor: pointer; width: 450px;" class="card rounded p-3"
aria-current="true">
<div>
<div class="d-flex w-100 justify-content-between mb-1">
<div class="d-flex" style="gap: 0.75rem;">
<h5>{{ product.name | titlecase}}</h5>
<span style="color: darkred;">${{product.price}}</span>
</div>
<div class="dropdown">
<button class="btn btn-dark dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Manage Product
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" >Add to Cart</a></li>
<li><a class="dropdown-item" data-bs-toggle="modal" data-bs-target="#staticBackdrop" style="cursor: pointer;" (click)="formOpen(product)">Edit</a></li>
<li><a class="dropdown-item" style="cursor: pointer;">Delete</a></li>
</ul>
</div>
</div>
<div class="d-flex flex-row align-items-center" [routerLink]="product.name" (click)="emitProduct(product)">
<img [src]="product.imagePath[0]" style="max-height: 175px">
<ul class="product-desc">
<li>{{productDescList[0]}}</li>
<li>{{productDescList[1]}}</li>
</ul>
</div>
</div>
</div>
<app-modal-pop></app-modal-pop>
product-form.component.html:
<form [formGroup]="productForm">
<h5>{{editMode? 'Edit Product': 'Create Product'}}</h5>
<div>
<app-input-field label="Name" [control]="productForm.get('name')"></app-input-field>
</div>
<div>
<app-input-field label="Description" [control]="productForm.get('description')"></app-input-field>
</div>
<div>
<app-input-field label="Specification" [control]="productForm.get('specification')"></app-input-field>
</div>
<div>
<app-input-field label="Price" [control]="productForm.get('price')"></app-input-field>
</div>
<div>
<app-input-field label="Image Path" [control]="productForm.get('imagePath')"></app-input-field>
</div>
<div>
<app-input-field label="Warranty" [control]="productForm.get('warranty')"></app-input-field>
</div>
<button type="submit" class="btn btn-secondary">Create</button>
</form>
输入字段.component.html:
<label class="label">{{label}}:</label>
<input type="text" [formControl]="control" id="name" [ngClass]="{'alert-danger': showErrors()}">
<ng-container *ngIf="control.errors && control.dirty && control.touched">
<div style="color: red;" *ngIf="control.errors.required">
Name is required!
</div>
<div style="color: red;" *ngIf="control.errors.minlength">
3 minimum characters!
</div>
</ng-container>
您正在创建
this.product
之前访问它。
this.productService.$emitProduct.subscribe
它在之后被触发,您在表单初始化中使用this.product
它。
在构造函数中创建表单并在 OnInit 函数中初始化它
export class ProductFormComponent {
productReceived?: Subscription;
editMode: boolean = false;
product?: product;
productForm: FormGroup;
constructor(private productService: ProductService) {
this.productForm = new FormGroup({
name: new FormControl('', [Validators.required,Validators.minLength(3)]),
description: new FormControl(''),
specification: new FormControl(''),
price: new FormControl(''),
imagePath: new FormControl(''),
warranty: new FormControl(''),
});
}
ngOnInit() {
this.productReceived = this.productService.$emitProduct.subscribe((product: product) => {
if (product) {
this.product = product;
this.editMode = true;
this.productForm.patchValue({...this.product})
}
});
}
ngOnDestroy() {
this.productReceived.unsubscribe();
}
}