Angular: FormArray 没有迭代
Angular: FormArray is not iterating
Firstly sorry for creating a long post but I had no option other than
this as I need to explain where am facing issue.
我有一个表单,其中控件是 JSON 的数组。我已经创建了一个反应形式。下面是我的 JSON 和我的 TS 代码:
JSON(从后端请求中获取)
{
"questionList": [
{
"questionCategory": {
"questionCategoryName": "JAVA",
"id": 40,
"isActive": true,
"timestamp": "2020-06-12 14:06:47.325"
},
"difficultyLevel": 0,
"options": [
{
"answer": false,
"id": 2,
"optionText": "method",
"timestamp": "2020-06-18 17:17:11.75"
},
{
"answer": false,
"id": 3,
"optionText": "name",
"timestamp": "2020-06-18 17:17:11.753"
},
{
"answer": false,
"id": 4,
"optionText": "class",
"timestamp": "2020-06-18 17:17:11.758"
},
{
"answer": true,
"id": 1,
"optionText": "variable",
"timestamp": "2020-06-18 17:17:11.663"
}
],
"section": {
"marksPerQuestion": 3,
"id": 8,
"isActive": true
},
"id": 1,
"isActive": true,
"questionText": "What is a variable ?",
"timestamp": "2020-06-18 17:17:10.946"
},
{
"questionCategory": {
"questionCategoryName": "APTITUDE",
"id": 41,
"isActive": true
},
"difficultyLevel": 0,
"options": [
{
"answer": true,
"id": 6,
"optionText": "xyz",
"timestamp": "2020-06-17 21:50:48.975"
},
{
"answer": true,
"id": 5,
"optionText": "abc",
"timestamp": "2020-06-17 21:50:48.907"
}
],
"section": {
"marksPerQuestion": 2,
"id": 7,
"isActive": true,
"timestamp": "2020-06-12 14:08:14.181"
},
"id": 2,
"isActive": true,
"questionText": "What is def",
"timestamp": "2020-06-17 21:50:48.6"
}
],
"empty": false
}
此 JSON
的 TS 代码
updateQuestionForm = this.fb.group({
id: [], isActive: [], difficultyLevel: [0], questionText: [''],
questionCategory: this.fb.group({
id: [],
questionCategoryName: ['']
}),
section: this.fb.group({
id: [],
marksPerQuestion: ['']
}),
options: new FormArray([])
});
optionForm = this.fb.group({
id: [], optionText: [''], answer: []
});
onEdit(e) {
const formArray: FormArray = this.updateQuestionForm.get('options') as FormArray;
this.updateQuestionForm.controls['id'].setValue(e.id);
this.updateQuestionForm.controls['isActive'].setValue(e.isActive);
this.updateQuestionForm.controls['questionText'].setValue(e.questionText);
this.updateQuestionForm.controls['questionCategory'].setValue({
id: e.questionCategory.id,
questionCategoryName: e.questionCategory.questionCategoryName
});
this.updateQuestionForm.controls['section'].setValue({
id: e.section.id,
marksPerQuestion: e.section.marksPerQuestion
});
for(let i of e.options) {
this.optionForm.controls['id'].setValue(i.id);
this.optionForm.controls['optionText'].setValue(i.optionText);
this.optionForm.controls['answer'].setValue(i.answer);
formArray.push(new FormControl(this.optionForm.value));
}
console.log(this.updateQuestionForm.value);
}
get Status() {
return this.updateQuestionForm.get('isActive');
}
get Options(): FormArray {
return this.updateQuestionForm.get('options') as FormArray;
}
让我解释一下 TS 的内容:
首先,我正在创建一个 updateQuestionForm
形式,它是 JSON 的主要形式。
optionForm
的第二种形式是针对 updateQuestionForm
的 options
FormArray。
我创建了第二种形式,因为我需要数组中的某些控件。所以这在我脑海中留下了深刻的印象。
onEdit()
方法由单击按钮触发,该按钮单击从 Mat-Table
.
获取 JSON
HTML形式
<form [formGroup]="updateQuestionForm" (submit)="onUpdateQuestionForm()">
<div class="row">
<div class="col-md-4">
<mat-form-field>
<mat-label>Enter Question</mat-label>
<input matInput formControlName="questionText">
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field formGroupName="questionCategory">
<mat-label>Question Category</mat-label>
<mat-select formControlName="id">
<ng-container *ngFor="let q of QuestionCategory;">
<mat-option [value]="q.id">{{ q.questionCategoryName }}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field formGroupName="section">
<mat-label>Marks</mat-label>
<mat-select formControlName="id">
<ng-container *ngFor="let m of Marks;">
<mat-option [value]="m.id">{{ m.marksPerQuestion }}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<mat-label>Status</mat-label><br>
<mat-slide-toggle color="primary" formControlName="isActive">{{ Status ? 'Active' : 'Inactive' }}</mat-slide-toggle>
</div>
</div>
<h3>Options & Answers</h3>
<div formArrayName="options">
<div class="row" *ngFor="let o of Options.value; index as i" [formGroupName]="i">
<div class="col-md-6">
<mat-form-field>
<mat-label>Option</mat-label>
<input matInput formControlName="optionText">
</mat-form-field>
</div>
<div class="col-md-3">
<mat-label>Answer</mat-label><br>
<mat-slide-toggle color="primary" formControlName="answer">
{{ answer ? 'True' : 'False' }}
</mat-slide-toggle>
</div>
</div>
</div>
<button mat-flat-button type="submit" style="background-color: #28a745; color: white;">Update</button>
</form>
这是JSON的形式。我能够成功地获取和存储控件 questionCategory
、section
、isActive
、questionText
的值。 options
控件出现问题。我有 4 个选项(有 4 个 optionText
、4 个 answer
,每个都从数据库中获取;参考上面的示例 JSON)。
但是我无法显示控件。看起来 ngFor
里面的 formArrayName="options"
不起作用。 h2
之后,什么也没有了。
请帮帮我。仅供参考,我正在关注这个 link 的 formArrayName 循环部分。
对于您的用例,您不需要两个表单来更新问题数据并且您的代码看起来很复杂。
我已经简化了您的代码,它对我来说工作正常。你可以看看here.
我做了什么?
1) 基本上,我已经根据您的代码示例在 ngOnInit()
中创建了一个简单的表单结构。
2) 我编写了 updateQuestionData()
函数,我用 JSON 数据修补表单。我迭代了 options
并为每个 option
.
创建了一个表单组
您可以修改表单上的值并查看 updateQuestionForm
的更新方式。
我希望这能简化您的用例并优化您的代码。
Firstly sorry for creating a long post but I had no option other than this as I need to explain where am facing issue.
我有一个表单,其中控件是 JSON 的数组。我已经创建了一个反应形式。下面是我的 JSON 和我的 TS 代码:
JSON(从后端请求中获取)
{
"questionList": [
{
"questionCategory": {
"questionCategoryName": "JAVA",
"id": 40,
"isActive": true,
"timestamp": "2020-06-12 14:06:47.325"
},
"difficultyLevel": 0,
"options": [
{
"answer": false,
"id": 2,
"optionText": "method",
"timestamp": "2020-06-18 17:17:11.75"
},
{
"answer": false,
"id": 3,
"optionText": "name",
"timestamp": "2020-06-18 17:17:11.753"
},
{
"answer": false,
"id": 4,
"optionText": "class",
"timestamp": "2020-06-18 17:17:11.758"
},
{
"answer": true,
"id": 1,
"optionText": "variable",
"timestamp": "2020-06-18 17:17:11.663"
}
],
"section": {
"marksPerQuestion": 3,
"id": 8,
"isActive": true
},
"id": 1,
"isActive": true,
"questionText": "What is a variable ?",
"timestamp": "2020-06-18 17:17:10.946"
},
{
"questionCategory": {
"questionCategoryName": "APTITUDE",
"id": 41,
"isActive": true
},
"difficultyLevel": 0,
"options": [
{
"answer": true,
"id": 6,
"optionText": "xyz",
"timestamp": "2020-06-17 21:50:48.975"
},
{
"answer": true,
"id": 5,
"optionText": "abc",
"timestamp": "2020-06-17 21:50:48.907"
}
],
"section": {
"marksPerQuestion": 2,
"id": 7,
"isActive": true,
"timestamp": "2020-06-12 14:08:14.181"
},
"id": 2,
"isActive": true,
"questionText": "What is def",
"timestamp": "2020-06-17 21:50:48.6"
}
],
"empty": false
}
此 JSON
的 TS 代码updateQuestionForm = this.fb.group({
id: [], isActive: [], difficultyLevel: [0], questionText: [''],
questionCategory: this.fb.group({
id: [],
questionCategoryName: ['']
}),
section: this.fb.group({
id: [],
marksPerQuestion: ['']
}),
options: new FormArray([])
});
optionForm = this.fb.group({
id: [], optionText: [''], answer: []
});
onEdit(e) {
const formArray: FormArray = this.updateQuestionForm.get('options') as FormArray;
this.updateQuestionForm.controls['id'].setValue(e.id);
this.updateQuestionForm.controls['isActive'].setValue(e.isActive);
this.updateQuestionForm.controls['questionText'].setValue(e.questionText);
this.updateQuestionForm.controls['questionCategory'].setValue({
id: e.questionCategory.id,
questionCategoryName: e.questionCategory.questionCategoryName
});
this.updateQuestionForm.controls['section'].setValue({
id: e.section.id,
marksPerQuestion: e.section.marksPerQuestion
});
for(let i of e.options) {
this.optionForm.controls['id'].setValue(i.id);
this.optionForm.controls['optionText'].setValue(i.optionText);
this.optionForm.controls['answer'].setValue(i.answer);
formArray.push(new FormControl(this.optionForm.value));
}
console.log(this.updateQuestionForm.value);
}
get Status() {
return this.updateQuestionForm.get('isActive');
}
get Options(): FormArray {
return this.updateQuestionForm.get('options') as FormArray;
}
让我解释一下 TS 的内容:
首先,我正在创建一个 updateQuestionForm
形式,它是 JSON 的主要形式。
optionForm
的第二种形式是针对 updateQuestionForm
的 options
FormArray。
我创建了第二种形式,因为我需要数组中的某些控件。所以这在我脑海中留下了深刻的印象。
onEdit()
方法由单击按钮触发,该按钮单击从 Mat-Table
.
HTML形式
<form [formGroup]="updateQuestionForm" (submit)="onUpdateQuestionForm()">
<div class="row">
<div class="col-md-4">
<mat-form-field>
<mat-label>Enter Question</mat-label>
<input matInput formControlName="questionText">
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field formGroupName="questionCategory">
<mat-label>Question Category</mat-label>
<mat-select formControlName="id">
<ng-container *ngFor="let q of QuestionCategory;">
<mat-option [value]="q.id">{{ q.questionCategoryName }}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-3">
<mat-form-field formGroupName="section">
<mat-label>Marks</mat-label>
<mat-select formControlName="id">
<ng-container *ngFor="let m of Marks;">
<mat-option [value]="m.id">{{ m.marksPerQuestion }}</mat-option>
</ng-container>
</mat-select>
</mat-form-field>
</div>
<div class="col-md-2">
<mat-label>Status</mat-label><br>
<mat-slide-toggle color="primary" formControlName="isActive">{{ Status ? 'Active' : 'Inactive' }}</mat-slide-toggle>
</div>
</div>
<h3>Options & Answers</h3>
<div formArrayName="options">
<div class="row" *ngFor="let o of Options.value; index as i" [formGroupName]="i">
<div class="col-md-6">
<mat-form-field>
<mat-label>Option</mat-label>
<input matInput formControlName="optionText">
</mat-form-field>
</div>
<div class="col-md-3">
<mat-label>Answer</mat-label><br>
<mat-slide-toggle color="primary" formControlName="answer">
{{ answer ? 'True' : 'False' }}
</mat-slide-toggle>
</div>
</div>
</div>
<button mat-flat-button type="submit" style="background-color: #28a745; color: white;">Update</button>
</form>
这是JSON的形式。我能够成功地获取和存储控件 questionCategory
、section
、isActive
、questionText
的值。 options
控件出现问题。我有 4 个选项(有 4 个 optionText
、4 个 answer
,每个都从数据库中获取;参考上面的示例 JSON)。
但是我无法显示控件。看起来 ngFor
里面的 formArrayName="options"
不起作用。 h2
之后,什么也没有了。
请帮帮我。仅供参考,我正在关注这个 link 的 formArrayName 循环部分。
对于您的用例,您不需要两个表单来更新问题数据并且您的代码看起来很复杂。
我已经简化了您的代码,它对我来说工作正常。你可以看看here.
我做了什么?
1) 基本上,我已经根据您的代码示例在 ngOnInit()
中创建了一个简单的表单结构。
2) 我编写了 updateQuestionData()
函数,我用 JSON 数据修补表单。我迭代了 options
并为每个 option
.
您可以修改表单上的值并查看 updateQuestionForm
的更新方式。
我希望这能简化您的用例并优化您的代码。