如何将输入数组绑定到 Angular 中的模型
How to bind array of inputs to model in Angular
有人可以帮我写下面的代码,并告诉我为什么它不起作用。我正在从字符串数组创建一系列输入,我想将每个输入值绑定到字符串数组中相应的槽。好像挺标准的,不过我好像没看懂。
下面两种情况我都试过了,但是Colors数组(=string[])还是空的!
<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>
您似乎忘记关闭 "tr" 标签。
Afaik ngModel 要求变量是 class 的 属性。
您应该尝试使用响应式表单
@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);
}
然后在你的 html 中像这样}
<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>
我是临时写的,所以不知道它是否有效。但是通过一些调整它应该。
字符串在 JavaScript 中是不可变的,这意味着我们不能将 ngModel 绑定到它们。您可以很容易地将数组转换为具有键颜色和字符串值的对象数组。这将解决您的绑定问题。这是一些代码。我还整理了一个 stackbitz 给你看。
不过,我还是推荐 Joey gough 的回答。该代码感觉更正确,"the angular way" 解决了这个问题。
祝你好运!
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}}
可以使用 [(ngModel)] 或 ReactiveForms。
使用 [(ngModel)] 的问题是您无法遍历自己的数组。
//***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>
但你可以使用
<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}}
是的是 work-around:不迭代颜色,只是在使用 String.repeat 和拆分
动态创建的数组上
' '.repeat(Colors.length).split('') //a string of same length that Colors.length
使用ReactiveForm,最好使用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}}
您可以看到 stackblitz
有人可以帮我写下面的代码,并告诉我为什么它不起作用。我正在从字符串数组创建一系列输入,我想将每个输入值绑定到字符串数组中相应的槽。好像挺标准的,不过我好像没看懂。
下面两种情况我都试过了,但是Colors数组(=string[])还是空的!
<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>
您似乎忘记关闭 "tr" 标签。
Afaik ngModel 要求变量是 class 的 属性。
您应该尝试使用响应式表单
@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);
}
然后在你的 html 中像这样}
<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>
我是临时写的,所以不知道它是否有效。但是通过一些调整它应该。
字符串在 JavaScript 中是不可变的,这意味着我们不能将 ngModel 绑定到它们。您可以很容易地将数组转换为具有键颜色和字符串值的对象数组。这将解决您的绑定问题。这是一些代码。我还整理了一个 stackbitz 给你看。
不过,我还是推荐 Joey gough 的回答。该代码感觉更正确,"the angular way" 解决了这个问题。 祝你好运!
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}}
可以使用 [(ngModel)] 或 ReactiveForms。
使用 [(ngModel)] 的问题是您无法遍历自己的数组。
//***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>
但你可以使用
<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}}
是的是 work-around:不迭代颜色,只是在使用 String.repeat 和拆分
动态创建的数组上' '.repeat(Colors.length).split('') //a string of same length that Colors.length
使用ReactiveForm,最好使用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}}
您可以看到 stackblitz