#angular #forms #crud #formgroups
#angular #формы #crud #formgroups
Вопрос:
Я создаю форму для сбора данных из поля ввода в Angular.
Допустим, у меня есть (студент, преподаватель, администрация), который заполняет форму.
Они (2 или все) разделяют некоторые поля (день рождения, имя, фамилия), которые можно использовать повторно, и другие поля, которые различны для всех (рабочий адрес, домашний адрес, почтовый адрес) и отличаются только для 2 (идентификатор студента, идентификатор факультета).
Возможно ли иметь несколько групп форм для этой цели? Как бы я подошел к этому, если у каждого из них много полей?
Ответ №1:
Этого можно достичь с помощью реактивных форм на основе моделей с использованием интуитивно понятной библиотеки @rxweb / reactive-form-validators, которую я нашел в npm
npm i @rxweb/reactive-form-validators
Начните с создания класса модели, имеющего свойства, которые вам нужны в вашей formgroup, как показано ниже
import { prop, } from "@rxweb/reactive-form-validators"
export class User {
@prop()
firstName: string;
@prop()
lastName: string;
@prop()
emailAddress: string;
}
@prop() определяет свойство, которое можно использовать для инициализации FormControl с использованием formGroup
метода RxFormBuilder
. Эта модель может быть позже в других компонентах, чтобы повторно использовать эти свойства и создавать FormGroup, не записывая один и тот же код несколько раз
import { Component, OnInit } from '@angular/core';
import { FormGroup } from "@angular/forms"
import { RxFormBuilder } from '@rxweb/reactive-form-validators';
import { User } from './user.model';
@Component({
selector: 'app-user-add',
templateUrl: './user-add.component.html'
})
export class UserAddComponent implements OnInit {
userFormGroup: FormGroup
constructor(
private formBuilder: RxFormBuilder
) { }
ngOnInit() {
let user = new User();
this.userFormGroup = this.formBuilder.formGroup(user);
}
}
Компонентный HTML-файл выглядит следующим образом:
<form *ngIf="userFormGroup" [formGroup]="userFormGroup">
<div class="form-group">
<label>FirstName</label>
<input type="text" formControlName="firstName" class="form-control" />
</div>
<div class="form-group">
<label>LastName</label>
<input type="text" formControlName="lastName" class="form-control" />
</div>
<div class="form-group">
<label>Email Address</label>
<input type="text" formControlName="emailAddress" class="form-control" />
</div>
<button [disabled]="!userFormGroup.valid" class="btn btn-primary">
Submit
</button>
</form>
Вот полный пример на stackblitz
Если вы хотите расширить класс и добавить дополнительные свойства в FormGroup, вы можете использовать функцию абстракции класса, доступную в той же библиотеке, наряду с этим она поставляется со многими встроенными средствами проверки, что упрощает выполнение проверок
Чтобы узнать больше об этом подходе, пожалуйста, обратитесь к Упрощенным реактивным формам
Ответ №2:
Если вы используете реактивные формы, это может показаться заманчивым, но это довольно просто, когда вы понимаете, что FormGroup
это всего лишь объект JS. Из-за этого вы можете использовать их как любой другой объект JS.
Более простым способом было бы реализовать метод, который делает это в сервисе, и использовать ваши знания объектов JS / TS:
private commonFields;
private roleBasedFields;
private addressForm;
constructor() {
this.commonFields = {
firstName: '',
lastName: ['', Validators.required],
birthday: [null, Validators.required]
};
this.addressForm = {
street: '',
streetNo: null,
zip: null,
city: '',
// and so on...
};
this.roleBasedFields = {
student: {
homeAddress: addressForm,
// add other fields related to student here
},
faculty: {
workAddress: addressForm,
// add other fields here
},
administration: {
mailingAddress: {
...addressForm,
department: ['', Validators.required]
// if the address object is different for a certain role, you can add them like this
},
// add other fields here
},
};
}
buildForm(role: 'student' | 'faculty' | 'administration'): FormGroup {
return new FormGroup({
...this.commonFields,
...this.roleBasedFields[role]
});
}
И в компоненте, в зависимости от того, как вы хотите его реализовать, используйте его как:
someForm: FormGroup;
formArray: FormArray;
ngOnInit() {
this.someForm = this.thatServiceAbove.buildForm('student');
// if it goes in an array
this.formArray = new FormArray([]);
}
// method to push the FormGroup in a FormArray:
generateForm(role: 'student' | 'faculty' | 'administration') {
this.formArray.push(this.thatServiceAbove.buildForm(role));
}
Вы поняли идею: D