Angular 2 удалите все элементы из формы
У меня есть массив форм внутри формообразователя, и я динамически меняю формы, то есть на данные загрузки клика из приложения 1 и т.д.
Проблема, с которой я сталкиваюсь, заключается в том, что все данные загружаются, но данные в formarray остаются и просто конкретизируют старые элементы с новыми.
Как удалить этот formarray только для новых элементов.
Я пробовал это
const control2 = <FormArray>this.registerForm.controls['other_Partners'];
control2.setValue([]);
но это не сработает.
Любые идеи?
спасибо
в nginit
ngOnInit(): void {
this.route.params.subscribe(params => { alert(params['id']);
if (params['id']) {
this.id = Number.parseInt(params['id']);
}
else { this.id = null;}
});
if (this.id != null && this.id != NaN) {
alert(this.id);
this.editApplication();
this.getApplication(this.id);
}
else
{
this.newApplication();
}
}
onSelect(Editedapplication: Application) {
this.router.navigate(['/apply', Editedapplication.id]);
}
editApplication() {
this.registerForm = this.formBuilder.group({
id: null,
type_of_proposal: ['', Validators.required],
title: ['', [Validators.required, Validators.minLength(5)]],
lead_teaching_fellow: ['', [Validators.required, Validators.minLength(5)]],
description: ['', [Validators.required, Validators.minLength(5)]],
status: '',
userID: JSON.parse(localStorage.getItem('currentUser')).username,
contactEmail: JSON.parse(localStorage.getItem('currentUser')).email,
forename: JSON.parse(localStorage.getItem('currentUser')).firstname,
surname: JSON.parse(localStorage.getItem('currentUser')).surname,
line_manager_discussion: true,
document_url: '',
keywords: ['', [Validators.required, Validators.minLength(5)]],
financial_Details: this.formBuilder.group({
id: null,
buying_expertise_description: ['', [Validators.required, Validators.minLength(2)]],
buying_expertise_cost: ['', [Validators.required]],
buying_out_teaching_fellow_cost: ['', [Validators.required]],
buying_out_teaching_fellow_desc: ['', [Validators.required, Validators.minLength(2)]],
travel_desc: ['', [Validators.required, Validators.minLength(2)]],
travel_cost: ['', [Validators.required]],
conference_details_desc: ['', [Validators.required, Validators.minLength(2)]],
conference_details_cost: ['', [Validators.required]],
}),
partners: this.formBuilder.array
(
[
//this.initEditPartner(),
//this.initEditPartner()
// this.initMultiplePartners(1)
]
),
other_Partners: this.formBuilder.array([
//this.initEditOther_Partners(),
])
});
}
getApplication(id)
{
this.applicationService.getAppById(id, JSON.parse(localStorage.getItem('currentUser')).username)
.subscribe(Response => {
if (Response.json() == false) {
this.router.navigateByUrl('/');
}
else {
this.application = Response.json();
for (var i = 0; i < this.application.partners.length;i++)
{
this.addPartner();
}
for (var i = 0; i < this.application.other_Partners.length; i++) {
this.addOther_Partner();
}
this.getDisabledStatus(Response.json().status);
(<FormGroup>this.registerForm)
.setValue(Response.json(), { onlySelf: true });
}
}
);
}
Ответы
Ответ 1
У меня была такая же проблема. Есть два способа решить эту проблему.
Сохранить подписку
Вы можете вручную очистить каждый элемент FormArray, вызвав функцию removeAt(i)
в цикле.
clearFormArray = (formArray: FormArray) => {
while (formArray.length !== 0) {
formArray.removeAt(0)
}
}
Преимущество этого подхода заключается в том, что любые подписки в вашем formArray
, например, зарегистрированные в formArray.valueChanges
, не будут потеряны.
См. Документацию FormArray для получения дополнительной информации.
Более чистый метод (но нарушает ссылки на подписку)
Вы можете заменить весь FormArray новым.
clearFormArray = (formArray: FormArray) => {
formArray = this.formBuilder.array([]);
}
Этот подход вызывает проблему, если вы подписаны на наблюдаемый formArray.valueChanges
! Если вы замените FromArray новым массивом, вы потеряете ссылку на наблюдаемое, на которое вы подписаны.
Ответ 2
Или вы можете просто очистить элементы управления
this.myForm= {
name: new FormControl(""),
desc: new FormControl(""),
arr: new FormArray([])
}
Добавить что-то array
const arr = <FormArray>this.myForm.controls.arr;
arr.push(new FormControl("X"));
Очистить массив
const arr = <FormArray>this.myForm.controls.arr;
arr.controls = [];
Когда у вас есть несколько вариантов выбора и очистки, иногда это не обновляет представление. Обходной путь должен добавить
arr.removeAt(0)
ОБНОВИТЬ
Более элегантным решением для использования массивов форм является использование метода получения в верхней части вашего класса, а затем вы можете получить к нему доступ.
get inFormArray(): FormArray {
this.myForm.get('inFormArray') as FormArray;
}
И использовать его в шаблоне
<div *ngFor="let c of inFormArray; let i = index;" [formGroup]="i">
other tags...
</div>
Сброс:
inFormArray.reset();
От себя:
inFormArray.push(new FormGroup({}));
Удалить значение по индексу: 1
inFormArray.removeAt(1);
Ответ 3
Начиная с Angular 8+, вы можете использовать clear()
для удаления всех элементов управления в FormArray:
const arr = new FormArray([
new FormControl(),
new FormControl()
]);
console.log(arr.length); // 2
arr.clear();
console.log(arr.length); // 0
Для предыдущих версий рекомендуется:
while (arr.length) {
arr.removeAt(0);
}
https://angular.io/api/forms/FormArray#clear
Ответ 4
Angular v4.4, если вам нужно сохранить ту же ссылку на экземпляр FormArray, попробуйте следующее:
purgeForm(form: FormArray) {
while (0 !== form.length) {
form.removeAt(0);
}
}
Ответ 5
Предупреждение!
Документация Angular v6.1.7 FormArray гласит:
Чтобы изменить элементы управления в массиве, используйте методы push, insert или removeAt в самом FormArray. Эти методы обеспечивают правильное отслеживание элементов управления в иерархии форм. Не изменяйте массив AbstractControls, используемый для непосредственного создания экземпляра FormArray, так как это приводит к странному и неожиданному поведению, такому как обнаружение неработающих изменений.
Имейте это в виду, если вы используете splice
функцию непосредственно на controls
массива, как один из ответа предложил.
Используйте функцию removeAt
.
while (formArray.length !== 0) {
formArray.removeAt(0)
}
Ответ 6
Предоставляя структуру данных для того, что вы будете заменять информацию в массиве совпадающими с тем, что уже существует, вы можете использовать patchValue
https://angular.io/docs/ts/latest/api/forms/index/FormArray-class.html#!#reset-anchor
patchValue (значение: any [], {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Исправляет значение FormArray. Это принимает массив, который соответствует структуре элемента управления, и будет сделайте все возможное, чтобы сопоставить значения с правильными элементами управления в группе.
Он принимает как суперэлементы, так и подмножества массива без металирования ошибка.
const arr = new FormArray([
new FormControl(),
new FormControl()
]);
console.log(arr.value); // [null, null]
arr.patchValue(['Nancy']);
console.log(arr.value); // ['Nancy', null]
В качестве альтернативы вы можете использовать reset
reset (значение: any, {onlySelf, emitEvent}?: {onlySelf?: boolean, emitEvent?: boolean}): void Сбрасывает FormArray. Это означает по умолчанию:
Массив и все потомки отмечены нетронутыми. Массив и все потомки отмечены нетронутыми. Значение всех потомков будет нулевые или нулевые карты. Вы также можете reset указать определенное состояние формы передавая в массив состояний, который соответствует структуре контроль. Состояние может быть автономным значением или объектом состояния формы с как значением, так и отключенным статусом.
this.arr.reset(['name', 'last name']);
console.log(this.arr.value); // ['name', 'last name']
ИЛИ
this.arr.reset([ {value: 'name', disabled: true}, 'last' ]);
console.log(this.arr.value); // ['name', 'last name']
console.log(this.arr.get(0).status); // 'DISABLED'
Вот развернутая демонстрация Plunker из какой-то более ранней работы моей демонстрации очень простого использования каждого из них.
Ответ 7
Обновление: Angular 8 наконец-то получил метод для очистки массива FormArray.clear()
Ответ 8
Angular 8
просто используйте метод clear()
для formArrays:
(this.invoiceForm.controls['other_Partners']).clear();
Ответ 9
Цикл while удалит все элементы, если массив содержит 100 элементов. Вы можете очистить оба элемента управления и значения свойства FormArray, как показано ниже.
clearFormArray = (formArray: FormArray) => {formArray.controls = []; formArray.setValue([]); formArray.setValue([]); } }
Ответ 10
в последней версии вы можете использовать FormArray.reset()
Ответ 11
Чтобы сохранить код в чистоте, я создал следующий метод расширения для тех, кто использует Angular 7 и ниже. Это также может быть использовано для расширения любой другой функциональности Реактивных форм.
import { FormArray } from '@angular/forms';
declare module '@angular/forms/src/model' {
interface FormArray {
clearArray: () => FormArray;
}
}
FormArray.prototype.clearArray = function () {
const _self = this as FormArray;
_self.controls = [];
_self.setValue([]);
_self.updateValueAndValidity();
return _self;
}
Ответ 12
Начиная с Angular 8, вы можете использовать this.formArray.clear()
для очистки всех значений в массиве форм.
Это более простая и эффективная альтернатива удалению всех элементов один за другим.
Ответ 13
Я никогда не пытался использовать formArray, я всегда работал с FormGroup, и вы можете удалить все элементы управления, используя:
Object.keys(this.formGroup.controls).forEach(key => {
this.formGroup.removeControl(key);
});
являясь formGroup, является экземпляром FormGroup.