¿Podría alguien ayudarme con el siguiente código y darme una razón por la que no funciona? Estoy creando una serie de entradas de una matriz de cadenas y quiero vincular cada valor de entrada a su ranura correspondiente en la matriz de cadenas. Parece ser bastante estándar, pero parece que no entiendo el problema.
He intentado los siguientes dos casos, ¡pero la matriz Colors (= string []) permanece vacía!
<tr *ngFor="let color of Colors; let i = index;">
<td>
<mat-form-field>
<input required matInput placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [(ngModel)]="color">
</mat-form-field>
</td>
</tr>
<tr *ngFor="let color of Colors; let i = index;">
<td>
<mat-form-field>
<input required matInput placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [(ngModel)]="Colors[i]">
</mat-form-field>
</td>
</tr>
4 respuestas
Las cadenas son inmutables en JavaScript, lo que significa que no podemos vincular ngModel a ellas. Podría convertir fácilmente su matriz en una matriz de objetos con el color clave y el valor de sus cadenas. Esto solucionaría su problema vinculante. Aquí hay un código. También pirateé un stackbitz para mostrarte.
Sin embargo, recomendaría la respuesta de Joey Gough. Ese código se siente más correcto y "la forma angular" de resolver esto. ¡Buena suerte!
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
Colors = [{color: 'stringColor1'}, {color: 'stringColor2'}]
}
<tr *ngFor="let item of Colors; let i = index;">
{{i}}
<td>
<input required placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [(ngModel)]="item.color">
</td>
</tr>
{{Colors | json}}
Ver: https://stackblitz.com/edit/angular-sj623x
Afaik ngModel requiere que la variable sea una propiedad de la clase.
Deberías intentar usar formas reactivas
@Input() colors: string[];
public formGroup: FormGroup;
constructor(private formBuilder: FormBuilder) {
}
ngOnInit() {
const formControls = {};
this.colors.forEach(e => {
formControls[e]: new FormControl(e);
}
this.formGroup = this.formBuilder.group(formControls);
}
Luego en tu html algo como esto}
<tr *ngFor="let color of Colors; let i = index;" [formGroup]="formGroup">
<td>
<mat-form-field>
<input required matInput placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [formControlName]="color">
</mat-form-field>
</td>
</tr>
Escribí eso sobre la marcha, así que no sé si funciona. Pero con algunos ajustes, debería.
Es posible usar [(ngModel)] en formularios reactivos.
El problema si usa [(ngModel)] es que no puede iterar sobre la propia matriz.
//***WRONG**, you change "Colors" in input and is iterating over Colors
//you see that your form is "unestable"
<div *ngFor="let color of Colors; let i = index;">
<input required matInput placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [(ngModel)]="Colors[i]">
</div>
Pero puedes usar
<tr *ngFor="let color of ' '.repeat(Colors.length).split(''); let i = index;">
<td>
<mat-form-field>
<input required matInput placeholder="Color ({{ i + 1}})"
[name]="'color_' + i" [(ngModel)]="Colors[i]">
</mat-form-field>
</td>
</tr>
<hr/>
{{Colors|json}}
Sí, es una solución alternativa: no iterar sobre colores, solo sobre una matriz creada sobre la marcha usando String.repeat y split
' '.repeat(Colors.length).split('') //a string of same length that Colors.length
Usando ReactiveForm, es mejor usar un FormArray
<div *ngIf="formArray" [formGroup]="formArray">
<tr *ngFor="let control of formArray.controls;let i=index">
<td>
<mat-form-field>
<input matInput placeholder="Color ({{ i + 1}})" [name]="'color_' + i" [formControl]="control">
</mat-form-field>
</td>
</tr>
</div>
<hr/>
{{formArray?.value|json}}
Puede ver el stackblitz
Parece que olvidó cerrar la etiqueta "tr".
Preguntas relacionadas
Nuevas preguntas
arrays
Una matriz es una estructura de datos lineal ordenada que consta de una colección de elementos (valores, variables o referencias), cada uno identificado por uno o más índices. Cuando pregunte sobre variantes específicas de matrices, utilice estas etiquetas relacionadas en su lugar: [vector], [lista de matrices], [matriz]. Cuando utilice esta etiqueta, en una pregunta que sea específica de un lenguaje de programación, marque la pregunta con el lenguaje de programación que se está utilizando.