Возможно использование [(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}}
Да, это обходной путь: не перебирать цвета, а только массив, созданный на лету с помощью String.repeat и split
' '.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}}
Вы можете увидеть стекаблитц