我是新的Angular ,我认为我已经浪费了很多时间在一个非常简单的步骤。
我有一个非常简单的表单,用于在数据库中创建Question
实体。创建记录时,表单似乎工作正常。但是,当其打开以编辑现有记录时,“mat-selct”控制字段未被填充。这些下拉菜单也是从API加载的。
下面是代码。
component.ts
import { Component, Inject, inject, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, FormGroupDirective, Validators } from '@angular/forms';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Observable } from 'rxjs';
import { Question } from 'src/app/Models/Question';
import { QuestionCategory } from 'src/app/Models/QuestionCategory';
import { QuestionType } from 'src/app/Models/QuestionType';
import { StResponse } from 'src/app/Models/StResponse';
import { QuestionCategoryService } from 'src/app/Services/question-category.service';
import { QuestionTypeService } from 'src/app/Services/question-type.service';
import { QuestionService } from 'src/app/Services/question.service';
@Component({
selector: 'app-question-form',
templateUrl: './question-form.component.html',
styleUrls: ['./question-form.component.scss']
})
export class QuestionFormComponent implements OnInit {
// model: Question;
@ViewChild(FormGroupDirective)
formDirective!: FormGroupDirective;
questionForm!: FormGroup
questionTypes: QuestionType[] = []
questionCategories: QuestionCategory [] = [];
constructor(private _fb: FormBuilder,
private _service: QuestionService,
private _quesCategoryServ: QuestionCategoryService,
private _quesTypeServ: QuestionTypeService,
@Inject(MAT_DIALOG_DATA) private data: Question
) {
}
ngOnInit(): void {
console.log('QF Oninit', this.data);
this._quesCategoryServ.getAll().subscribe((sr:StResponse)=>{
console.log('QesComp:', sr.data)
this.questionCategories = sr.data.QuestionCategory;
});
this._quesTypeServ.getAll().subscribe((sr:StResponse)=>{
console.log('QesComp:', sr.data)
this.questionTypes = sr.data.QuestionType;
});
this.questionForm = this._fb.group({
shortText: ['',Validators.required],
text: ['',Validators.required],
textInfo: [''],
questionType: [null,Validators.required],
questionCategory:[null,Validators.required],
});
if(this.data){
console.log('oninit-forEdit')
this.questionForm.patchValue({
shortText: this.data.shortText,
text: this.data.text,
textInfo: this.data.textInfo,
questionType: this.data.questionType,
questionCategory: this.data.questionCategory,
});
}
}
onFormSubmit():void {
if(this.questionForm.valid){
console.log('submited form values',this.questionForm.value);
this._service.add(this.questionForm.value).subscribe({
next: (val: StResponse) => {
alert('Question Added')
// this.questionForm.reset();
this.formDirective.resetForm();
console.log('form resetted!')
},
error: (err: any) =>{
console.error(err);
}
})
}
}
// FormControl fields references for validation
get shortText() { return this.questionForm.get('shortText'); }
get text() { return this.questionForm.get('text'); }
get textInfo() { return this.questionForm.get('textInfo'); }
get questionType() { return this.questionForm.get('questionType'); }
get questionCategory() { return this.questionForm.get('questionCategory'); }
}
component.html
<h1 mat-dialog-title>Question</h1>
<form [formGroup]="questionForm" (ngSubmit)="onFormSubmit()">
<div mat-dialog-content class="content">
<div class="row">
<mat-form-field appearance="outline">
<mat-label>Short Text</mat-label>
<input matInput type="text" placeholder="Ex. Wheels." formControlName="shortText">
<mat-error *ngIf="shortText?.invalid">Enter short text.</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field appearance="outline">
<mat-label>Question</mat-label>
<input matInput type="text" placeholder="Ex. Undamaged, All nuts tight." formControlName="text">
<mat-error *ngIf="text?.invalid">Please enter question text.</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field appearance="outline">
<mat-label>Details</mat-label>
<textarea matInput placeholder="Ex. Any details to further explain this question." formControlName="textInfo"></textarea>
</mat-form-field>
</div>
<div class="row">
<mat-form-field appearance="outline">
<mat-label>Type</mat-label>
<mat-select formControlName="questionType" >
<mat-option *ngFor="let typeOption of questionTypes" [value]="typeOption">
{{typeOption.code}}
</mat-option>
</mat-select>
<mat-error *ngIf="questionType?.invalid">You must make a selection</mat-error>
</mat-form-field>
</div>
<div class="row">
<mat-form-field appearance="outline">
<mat-label>Category</mat-label>
<mat-select formControlName="questionCategory" >
<mat-option *ngFor="let categoryOption of questionCategories" [value]="categoryOption">
{{categoryOption.code}}
</mat-option>
</mat-select>
<mat-error *ngIf="questionCategory?.invalid">You must make a selection</mat-error>
</mat-form-field>
</div>
</div>
<div mat-dialog-actions class="action">
<button mat-raised-button mat-dialog-close>Close</button>
<button mat-raised-button color="primary" type="submit">save</button>
</div>
</form>
export class Question{
id: number;
shortText: string;
text: string;
textInfo: string;
questionType: QuestionType;
questionCategory: QuestionCategory;
constructor(){
this.id = 0;
this.shortText = '';
this.text = '';
this.textInfo = '';
this.questionType = new QuestionType();
this.questionCategory = new QuestionCategory();
}
}
export class QuestionType{
id: number;
code: string;
constructor(){
this.id = 0;
this.code = '';
}
}
export class QuestionCategory{
id: number;
code: string;
name: string;
constructor(){
this.id = 0;
this.code = '';
this.name = '';
}
}
一些其他发现正在填充shortText、text、TextInfo的其他输入。只有“垫选择”未加载。我一定是错过了一些愚蠢的事情,因为即使是选择的值也没有填充,它们就像我在编辑时将它们保留为空白,然后再次按保存。这些值被提交并保存在数据库中。
我也试过form.setValue()
方法,但仍然没有运气。
// part of ngOnInit()
if(this.data){
console.log('oninit-forEdit')
this.questionForm.patchValue({
shortText: this.data.shortText,
text: this.data.text,
textInfo: this.data.textInfo,
// questionType: this.data.questionType,
// questionCategory: this.data.questionCategory,
});
const selectedCategory = this.questionCategories.find(category => category.id === this.data.questionCategory.id);
const selectedType = this.questionTypes.find(type => type.id === this.data.questionType.id);
this.questionForm.get('questionCategory')?.setValue(selectedCategory);
this.questionForm.get('questionType')?.setValue(selectedType);
}
}
任何帮助或指导都会有帮助。谢谢
1条答案
按热度按时间cvxl0en21#
当决定将哪个选项标记为选中时,Angular通过标识(===)比较值。
这在编辑表单时不起作用,因为当前表单控件值不等于列表中的任何值,即。它们不是相同的对象(即使它们具有相同的结构)。
questionTypes
是通过调用this._quesTypeServ.getAll
获取的,当前表单控件值为data.questionType
。要让Angular以其他方式比较值,您可以使用
compareWith
输入SelectControlValueAccessor
。我们可以通过id比较值,因为该属性对于每个对象都是唯一的:
在模板中:
关于compareWith的文档:https://angular.io/api/forms/SelectControlValueAccessor#customizing-option-selection