Tengo una aplicación Angular2 con un botón que puede agregar otro préstamo a mis préstamos. Mi *ngFor es bastante simple también:
<div *ngFor="let loan of myLoans"> <label>{{loan.name}}</label> <input type="text" name="loan.name" [(ngModel)]="loan.amount"> </div> myLoans es una matriz de objetos de préstamo con parámetros de name y amount . Mi botón también es muy simple.
<button id="addLoan" type="button" (click)="addLoan()">Legg til lån</button>La función añadirPréstamo():
addLoan(): void{ var newLoan = new Loan(); this.myLoans.push(newLoan); }Mi problema es que cuando agrego un nuevo préstamo en la lista, cualquier valor que tenía en el campo de entrada para mis otros préstamos vuelve a 0 o cualquier valor que establecí en el constructor para el objeto de préstamo.
Cargar la aplicación muestra esta imagen
ngModel funciona al escribir un número
Después de presionar el botón "Legg til lån", el valor de la primera entrada se restablece
ngModel sigue funcionando para la primera entrada si intento poner otro número
¿Alguien tiene una idea de lo que está pasando aquí?
AJT_82 está cerca del problema, ya que los nombres no únicos le están causando un problema, sin embargo, puede hacer una solución aún más simple, y una más en la línea de lo que probablemente quería, cambiando su plantilla html a esto
<div *ngFor="let loan of myLoans"> <label>{{loan.name}}</label> <input type="text" [name]="loan.name" [(ngModel)]="loan.amount"> </div>Observe el cambio de poner el nombre en [ ]. Esto garantizará que la plantilla mantenga un vínculo con el nombre y, siempre que el nombre de cada préstamo sea único, también lo será el identificador.
Actualización: si el nombre no es único, puede agregarle el índice para que sea único.
<div *ngFor="let loan of myLoans; let i=index"> <label>{{loan.name}}</label> <input type="text" [name]="loan.name + '_' + i" [(ngModel)]="loan.amount"> </div>Estoy 99% seguro de que está utilizando un formulario, sin tener atributos de name únicos, ya que ngModel funciona.
El atributo de nombre tiene que ser único para ser evaluado como campos separados. A Angular realmente no le importa el ngModel en los formularios, sino que mira el atributo de name en su lugar.
Tenga en cuenta que el atributo de nombre que ha establecido actualmente: name="loan.name" en realidad contiene solo la cadena literal de loan.name no el valor real de su modelo, por lo tanto, el nombre no es único.
Entonces, cuando está impulsando un nuevo loan , todos los demás préstamos obtienen el mismo valor que el valor recién impulsado, ya que todos los campos se evalúan como uno solo.
Esto se puede solucionar fácilmente agregando el índice en el atributo de nombre, por ejemplo:
<div *ngFor="let loan of myLoans; let i=index"> <label>{{loan.name}}</label> <input type="text" name="loan.name{{i}}" [(ngModel)]="loan.amount"> </div>El valor de la entrada se convierte en cero porque ha declarado que [(ngModel)] es el objeto iterador de *ngFor. Y cuando empuja un Objeto en blanco a la matriz de myLoans, ngModel cambia la entrada a cero (valor predeterminado para la cantidad)
Ejemplo:
myLoans = [0, 1, 2, 3]Cuando actualiza la página, [(ngModel]) vincula el último valor de la matriz a la entrada (3).
Si escribe 125 en la entrada,
Entonces también estás cambiando el valor de la última matriz
myLoans = [0, 1, 2, 125]Si presiona un nuevo elemento, Angular actualizará la entrada con el último valor de matriz
myLoans = [0, 1, 2, 125, 0]Input.value ahora = 0
Mi opinión: es una mala práctica usar ngModel dentro de un * ngFor, hay otra forma de hacer la misma tarea usando el evento (clic) y el Selector angular. Prueba esto en su lugar:
<input #loan ..> <button (click)="addLoan(loan.value)">Add Loan</button>