Модель компонента:
private SomeArray = [{ key: "Initial" }];
Пользователь может добавлять/удалять элементы динамически:
addField() {
this.SomeArray.push({ key: Math.random().toString() });
}
removeField(index: number) {
this.SomeArray.splice(index, 1);
}
Разметка шаблона:
<div class="col-xs-12">
<button (click)="addField()" type="button">Add</button>
</div>
<div *ngFor="let field of SomeArray; let i = index;">
<input [(ngModel)]="field.key" #modelField="ngModel" [name]=" 'SomeArray['+i+'].key' " type="text" class="form-control" required />
<div [hidden]="modelField.pristine || !(modelField.errors && modelField.errors.required)" class="alert alert-danger">
Required error
</div>
<button (click)="removeField(i)" class="btn btn-danger">Remove</button>
</div>
Это работает до тех SomeArray
пока пользователь не удалит какой-либо элемент из SomeArray
. Если я сначала добавлю несколько элементов:
и удалите один с 1 индексом:
то после добавления другого элемента Angular обработать его, поскольку элемент имеет как индекс 0, так и 1 (новый элемент "занимает" оба двух входа):
(элемент с ключом 0.1345... не отображается)
Стоит отметить элементы SomeArray
, как ожидалось, но сбой передачи данных. Что может быть причиной этого?
Обновление: благодаря комментариям @Stefan Svrkota и @AJT_82, он известен мне, проблема может быть решена путем добавления [ngModelOptions]="{standalone: true}"
к нужному вводу. Но я не мог перестать думать о причине проблемы по моей причине, не устанавливая standalone
опцию (для каждого атрибута имени есть уникальное значение, поэтому здесь ничего не было сделано).
Наконец, я обнаружил, что поведение происходит, когда элементы ввода находятся только в <form>
- здесь пример Plunker (причина этого вопроса заключается в создании шаблона с тегом формы).
Любые идеи такого поведения?
Причина, по которой это происходит, - ngFor
смешивает свойства name
при удалении некоторого элемента.
При использовании ngModel
внутри form
каждого ngModel
управление будет добавлено, чтобы сформировать коллекцию элементов управления.
Посмотрим, что произойдет, если мы добавили три элемента и нажали кнопку " Remove
второй".
1) SomeArray[1].key
- SomeArray[1].key
существует в controls
коллекцией
2) Step2 - SomeArray[1].key
был удален из коллекции controls
3) Шаг 3 - Html выглядит так:
4) Шаг4 Мы добавляем новый элемент
Таким образом formGroup
возвращает существующий элемент.
Как мы можем это решить?
1) Не заверните наши элементы управления в теге form
2) Добавьте атрибут ngNoForm
в форму
<form ngNoForm>
3) Использование
[ngModelOptions]="{standalone: true}
Со всеми тремя решениями выше:
Мы можем удалить привязку свойства [name]
Мы не можем использовать встроенную проверку группы форм
4) Используйте trackBy для ngFor
template.html
<div *ngFor="let field of SomeArray; let i = index; trackBy: trackByFn">
component.ts
trackByFn(i: number) {
return i;
}
Таким образом, наша встроенная форма будет работать правильно