جاوااسکریپت - چگونه مقادیر یک آرایه فرم پویا را در Angular 10 وصلهگذاری کنیم؟
من یک formArray پویا دارم، دادهها را ذخیره میکنم و همه چیز به خوبی کار میکند اما در وارد کردن مقادیر مشکل دارم، همچنین نتوانستم هیچ راه حل دقیقی به صورت آنلاین پیدا کنم.
کد زیر است،
<form [formGroup]="educationAndExperienceForm">
<div formArrayName="educationForm">
<div *ngFor="let education of educationAndExperienceForm.controls.educationForm['controls'];let i = index;"
[formGroupName]="i">
<h6 class="text-left circularBold" *ngIf="i == 0"><b>Highest Qualification</b></h6>
<input type="text" class="education-inputs w-100 mt-3" placeholder="School/College/University"
formControlName="school"
[ngClass]="{ 'input-error': submitted && educationAndExperienceForm.controls.educationForm.controls[i].invalid }">
<input type="text" class="education-inputs w-100 mt-3" placeholder="Degree Ex: Master's"
formControlName="degree"
[ngClass]="{ 'input-error': submitted && educationAndExperienceForm.controls.educationForm.controls[i].invalid }">
<input type="text" class="education-inputs w-100 mt-3"
placeholder="Field of Education Ex: Computer Science" formControlName="specialization"
[ngClass]="{ 'input-error': submitted && educationAndExperienceForm.controls.educationForm.controls[i].invalid }">
<div class="text-left">
<input type="text" class="education-inputs w-100 mt-3" placeholder="Graduate Year"
formControlName="passed_year"
[ngClass]="{ 'input-error': submitted && educationAndExperienceForm.controls.educationForm.controls[i].invalid }">
</div>
<div class="row text-right">
<div class="col-10"></div>
<div class="col-1">
<button type="button" class="btn deleteBtn" (click)="removeEducationFormGroup()">
<i class="fa fa-remove" style="font-size: 24px;" aria-hidden="true"></i>
</button>
</div>
</div>
<div class="text-left" *ngIf="!showAddAfterEducationHeading">
<button type="button" class="btn btn-light circularMedium mb-3 transparentBtn"
(click)="addEducationFormGroup()">
Add Education
</button>
</div>
</div>
<div class="text-left" *ngIf="showAddAfterEducationHeading">
<button type="button" class="btn btn-light circularMedium mb-3 transparentBtn"
(click)="addEducationFormGroup()">
Add Education
</button>
</div>
</div>
</form>
فایل TS
this.educationAndExperienceForm = this.fb.group({
'educationForm': this.fb.array([this.createEducationFormGroup()])
});
private createEducationFormGroup(): FormGroup {
return this.educationForm = this.fb.group({
'school': ['', Validators.required],
'degree': ['', Validators.required],
'specialization': ['', Validators.required],
'passed_year': ['', Validators.required]
})
}
در زیر کدی است که من برای وصله کردن مقادیر امتحان کردم،
1. One way
fetchQualificationById(){
this.apiService.fetchQualificationById(this.expertId).subscribe(res => {
console.log("Response Ed = "+JSON.stringify(res));
this.qualificationData = res['expertsQualification'];
});
let school = this.qualificationData['school'];
let degree = this.qualificationData['degree'];
let specialization = this.qualificationData['specialization'];
let passed_year = this.qualificationData['passed_year'];
this.educationAndExperienceForm.controls.educationForm.patchValue({
'school': school,
'degree': degree,
'specialization': specialization,
'passed_year': passed_year
})
// console.log("Get Qualification = "+JSON.stringify(this.educationAndExperienceForm.controls.educationForm.value))
}
2. Second way
fetchQualificationById(){
this.apiService.fetchQualificationById(this.expertId).subscribe(res => {
console.log("Response Ed = "+JSON.stringify(res));
this.qualificationData = res['expertsQualification'];
for (let education=0; education < res['expertsQualification'].length; education++){
const educationFormArray = this.educationAndExperienceForm.get("educationForm") as FormArray;
}
});
}
برای روشی که اول استفاده میکنم، خطای نمیتوان از forEach استفاده کرد را دریافت میکنم
ویرایش شد
اینجا فقط یک آرایه وجود دارد اما ما میتوانستیم یک آرایه خالی هم داشته باشیم، چرا اینطور است؟ در زیر کد TypeScript من آمده است
@Component({
selector: 'app-expert-education',
templateUrl: './expert-education.component.html',
styleUrls: ['./expert-education.component.css']
})
export class ExpertEducationComponent implements OnInit {
educationForm: FormGroup;
educationAndExperienceForm: FormGroup;
experienceForm: FormGroup;
submitted: boolean;
showAddAfterEducationHeading: boolean;
showAddAfterExperienceHeading: boolean;
expertId;
qualificationData: QualificationModel[] = [];
experienceData: ExperienceModel[] = [];
constructor(
private route: Router,
private fb: FormBuilder,
private apiService: ApiService
) {
this.submitted = false;
}
ngOnInit(): void {
// this.educationForm = this.fb.group({
// 'school': ['', Validators.required],
// 'degree': ['', Validators.required],
// 'field': ['', Validators.required],
// 'graduatedYear': ['', Validators.required],
// 'experience': ['', Validators.required],
// 'designation': ['', Validators.required],
// 'company': ['', Validators.required]
// })
this.expertId = sessionStorage.getItem('id_expert');
this.educationAndExperienceForm = this.fb.group({
'educationForm': this.fb.array([this.createEducationFormGroup()]),
'experienceForm': this.fb.array([this.createExperienceFormGroup()])
});
this.showAddAfterEducationHeading = false;
this.showAddAfterExperienceHeading = true;
this.fetchQualificationById();
this.fetchExperienceById();
}
addEducationFormGroup() {
this.showAddAfterEducationHeading = true;
const education = this.educationAndExperienceForm.get('educationForm') as FormArray;
education.push(this.createEducationFormGroup());
}
addExperienceFormGroup() {
this.showAddAfterExperienceHeading = true;
const experience = this.educationAndExperienceForm.get('experienceForm') as FormArray;
experience.push(this.createExperienceFormGroup());
}
removeEducationFormGroup(index) {
const education = this.educationAndExperienceForm.get('educationForm') as FormArray
if (education.length > 1) {
education.removeAt(index);
} else {
education.reset();
}
}
removeExperienceFormGroup(index) {
const experience = this.educationAndExperienceForm.get('experienceForm') as FormArray
if (experience.length > 1) {
experience.removeAt(index);
} else {
experience.reset();
}
}
private createEducationFormGroup(): FormGroup {
return this.educationForm = this.fb.group({
'school': ['', Validators.required],
'degree': ['', Validators.required],
'specialization': ['', Validators.required],
'passed_year': ['', Validators.required]
})
}
private createExperienceFormGroup(): FormGroup {
return this.experienceForm = this.fb.group({
'duration': ['', Validators.required],
'designation': ['', Validators.required],
'company_name': ['', Validators.required]
})
}
onSubmit() {
this.submitted = true;
console.log("Form = " + JSON.stringify(this.educationAndExperienceForm.controls.educationForm.value) + "\nValid = " + this.educationAndExperienceForm.valid)
if (this.educationAndExperienceForm.valid) {
this.apiService.saveExpertEducationAndExperience(this.educationAndExperienceForm.controls.educationForm.value, this.educationAndExperienceForm.controls.experienceForm.value, this.expertId).subscribe(res => {
console.log("Expert education & exp res = " + JSON.stringify(res));
this.route.navigate(['/expert-welcome/expert-services']);
})
}
}
back() {
this.route.navigate(['/expert-welcome/expert-profile']);
}
fetchQualificationById() {
this.apiService.fetchQualificationById(this.expertId).subscribe(res => {
this.qualificationData = res['expertsQualification'];
const control = <FormArray>this.educationAndExperienceForm.controls['educationForm'];
this.qualificationData.forEach(x => {
control.push(this.fb.group({
school: [x.school, Validators.required],
degree: [x.degree, Validators.required],
specialization: [x.specialization, Validators.required],
passed_year: [x.passed_year, Validators.required]
}));
});
});
}
fetchExperienceById() {
this.apiService.fetchExperienceById(this.expertId).subscribe(res => {
this.experienceData = res['expertExperience'];
const control = <FormArray>this.educationAndExperienceForm.controls['experienceForm'];
this.experienceData.forEach(x => {
control.push(this.fb.group({
duration: [x.duration, Validators.required],
designation: [x.designation, Validators.required],
company_name: [x.company_name, Validators.required],
}));
});
});
}
}
هر کمکی قابل تقدیر است.
پاسخ شماره ۱
مشکل به نظر میرسد که patchValue قادر به پر کردن formarrays نیست. شما میتوانید formarrays را مانند آرایههای معمولی با push() پر کنید.
با فرض اینکه this.qualificationData شما یک آرایه حاوی بسیاری از "expertsQualification" ها (نوع آرایه) است و کلاس/رابط ExpertsQualification دارای خصوصیات "school"، "degree"، "specialization" و "passed_year" باشد، شما میتوانید کارهای زیر را انجام دهید:
(this.educationAndExperienceForm.controls.educationForm as FormArray).reset(); //reset the FormArray
this.qualificationData.forEach(x => {
(this.educationAndExperienceForm.controls.educationForm as FormArray)
.push(this.fb.group({
school: [x.school, Validators.required],
degree: [x.degree, Validators.required],
specialization: [x.specialization, Validators.required],
passed_year: [x.passed_year, Validators.required]
});
};
.. بنابراین شما باید از طریق آرایه خود حلقه بزنید و برای هر عنصر یک FormGroup به FormArray اضافه کنید. لطفاً توجه داشته باشید که بسیار مهم است که آن را به FormArray تبدیل کنید، مانند
(this.educationAndExperienceForm.controls.educationForm as FormArray)
اگر این کار را نکنید، آن یک AbstractControl باقی میماند و نخواهید توانست از توابع آرایهای مانند push، pull و غیره استفاده کنید.
