* ngFor сброс всех значений формы при добавлении нового элемента ввода



У меня есть приложение Angular2 с кнопкой, которая может добавить еще один кредит к моим кредитам. Мой * ngFor также довольно прост:



    <div *ngFor="let loan of myLoans">
<label>{{loan.name}}</label>
<input type="text" name="loan.name" [(ngModel)]="loan.amount">
</div>


myLoans представляет собой массив объектов займа с параметрами name и amount. Моя кнопка также очень проста.



<button id="addLoan" type="button" (click)="addLoan()">Legg til lån</button>


Функция addLoan ():



addLoan(): void{
var newLoan = new Loan();
this.myLoans.push(newLoan);
}


Моя проблема заключается в том, что когда я добавляю новый кредит в список, любое значение, которое я имел в поле ввода для других моих кредитов, возвращается к 0 или любому значению, которое я установил в конструкторе для объекта кредита.

Загрузка приложения показывает эту картинку



И что теперь?



NgModel работает при вводе числа



Введите описание изображения здесь



После нажатия кнопки "Legg til lån" значение первого входа сбрасывается



Введите описание изображения здесь



NgModel все еще работает для первого ввода, если я попытаюсь ввести другое число



Введите описание изображения здесь



Кто-нибудь имеет представление о том, что такое что здесь происходит?

660   5  

5 ответов:

AJT_82 близок к проблеме, в том, что неуникальные имена вызывают у вас проблему, однако вы можете сделать еще более простое исправление, и еще одно в соответствии с тем, что вы, вероятно, хотели, изменив ваш шаблон html на этот

<div *ngFor="let loan of myLoans">
  <label>{{loan.name}}</label>
  <input type="text" [name]="loan.name" [(ngModel)]="loan.amount">
</div>

Обратите внимание на изменение имени в []. Это гарантирует, что шаблон сохраняет ссылку на имя, и до тех пор, пока имя каждого кредита уникально, то же будет и идентификатор.

Обновление: Если имя не уникально, вы можете добавить индекс к нему, чтобы сделать его уникальным, как так.

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" [name]="loan.name + '_' + i" [(ngModel)]="loan.amount">
</div>

Я на 99% уверен, что вы используете форму, не имея уникальных атрибутов name, так как ngModel работает.

Атрибут name должен быть уникальным, чтобы его можно было вычислить как отдельные поля. Angular на самом деле не заботится о ngModel в формах, но вместо этого смотрит на атрибут name.

Обратите внимание, что атрибут name, который вы в данный момент установили: name="loan.name" на самом деле содержит только строковый литерал loan.name, а не фактическое значение вашей модели, поэтому имя не является уникальным.

Итак, когда вы выталкивая новый loan, все остальные кредиты получают такое же значение, как и вновь выталкиваемое значение, так как все поля оцениваются как одно и то же.

Это можно легко исправить, добавив индекс в атрибут name, например:

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" name="loan.name{{i}}" [(ngModel)]="loan.amount">
</div>

Я попробовал ваш код, и он отлично работает для меня. Я предполагаю, что это может быть проблема компилятора. Попробуйте обновить библиотеки ng2 и typescript до последней версии. Вот пример частичного файла tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "typeRoots": ["node_modules/@types/"],
    "types": [
      "node",
      "es6-shim"
    ]
  }
}

Также избегайте использования "var" для объявления переменных. Используйте "let", чтобы сохранить область видимости переменной. Я думаю, что ваша проблема может быть связана с использованием var. Если вы используете старый компилятор, он может испортить ваш объект.

Значение входных данных становится нулевым, поскольку вы объявили [(ngModel)] итератором объекта *ngFor. И когда вы помещаете пустой объект в массив myLoans, ngModel изменяет входные данные на ноль (значение по умолчанию для amount)

Пример:

myLoans = [0, 1, 2, 3]

При обновлении страницы [(ngModel]) привязывает последнее значение массива к входу (3).

Если вы пишете 125 на входе,

Тогда вы также изменяете значение последнего массива

myLoans = [0, 1, 2, 125]

Если вы нажмете новый элемент Angular обновит входные данные с последним значением массива

myLoans = [0, 1, 2, 125, 0]

Ввод.значение now = 0


Мое мнение: это плохая практика использовать ngModel внутри *ngFor, есть другой способ выполнить ту же задачу с помощью события (click) и углового селектора. Попробуйте вместо этого:

<input #loan ..>
<button (click)="addLoan(loan.value)">Add Loan</button>

@Joo_Beck предложил использовать [name]=loan.name вместо name='loan.name'. Но это не сработало для меня. Я просто добавил индекс {{i}} с именем, как указано ниже, и он отлично работал.

<div *ngFor="let loan of myLoans; let i=index">
  <label>{{loan.name}}</label>
  <input type="text" name="loan.name{{i}}" [(ngModel)]="loan.amount">
</div>

Решение, которое сработало для меня, предложено @AJT_82. Спасибо за это!

Спасибо @ Cassiano, вы очень хорошо объяснили причину!

Comments

    Ничего не найдено.