ngModel не может правильно определить изменения массива

1

Модель компонента:

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. Если я сначала добавлю несколько элементов: Изображение 174551

и удалите один с 1 индексом:

Изображение 174551

то после добавления другого элемента Angular обработать его, поскольку элемент имеет как индекс 0, так и 1 (новый элемент "занимает" оба двух входа):

Изображение 174551

(элемент с ключом 0.1345... не отображается)

Стоит отметить элементы SomeArray, как ожидалось, но сбой передачи данных. Что может быть причиной этого?

Обновление: благодаря комментариям @Stefan Svrkota и @AJT_82, он известен мне, проблема может быть решена путем добавления [ngModelOptions]="{standalone: true}" к нужному вводу. Но я не мог перестать думать о причине проблемы по моей причине, не устанавливая standalone опцию (для каждого атрибута имени есть уникальное значение, поэтому здесь ничего не было сделано).

Наконец, я обнаружил, что поведение происходит, когда элементы ввода находятся только в <form> - здесь пример Plunker (причина этого вопроса заключается в создании шаблона с тегом формы).

Любые идеи такого поведения?

Теги:
angular
angular2-template

1 ответ

3
Лучший ответ

Причина, по которой это происходит, - ngFor смешивает свойства name при удалении некоторого элемента.

При использовании ngModel внутри form каждого ngModel управление будет добавлено, чтобы сформировать коллекцию элементов управления.

Посмотрим, что произойдет, если мы добавили три элемента и нажали кнопку " Remove второй".

1) SomeArray[1].key - SomeArray[1].key существует в controls коллекцией Изображение 174551

2) Step2 - SomeArray[1].key был удален из коллекции controls

Изображение 174551

3) Шаг 3 - Html выглядит так:

Изображение 174551

4) Шаг4 Мы добавляем новый элемент

Изображение 174551

Таким образом 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;
}

Пример плунжера

Таким образом, наша встроенная форма будет работать правильно

Ещё вопросы

Сообщество Overcoder
Наверх
Меню