如何在* ngFor中将ngModel与索引一起使用?

时间:2020-06-18 13:23:12

标签: angular typescript forms ngfor

我正在使用mat-inputs生成动态*ngFor。我想使用[(ngModel)]元素的索引将每个*ngFor值存储在不同的数组中(而不是*ngFor一个)。这是我在做什么:

<div  *ngFor="let item of items;let id = index;">

<mat-form-field >
  <mat-select  [(ngModel)]="differentArray[id].first"  (ngModelChange)="onSelection()">
    <mat-option *ngFor="let number of arrayOfNumbers" [value]="number">{{number}}</mat-option>
  </mat-select>
</mat-form-field> 

<mat-form-field>
  <mat-select  [(ngModel)]="differentArray[id].second"  (ngModelChange)="onSelection()">
    <mat-option *ngFor="let number of arrayOfNumbers" [value]="number" >{{number}}</mat-option>
  </mat-select>
</mat-form-field>

<mat-form-field >
  <mat-select  [(ngModel)]="differentArray[id].third"  (ngModelChange)="onSelection()">
    <mat-option *ngFor="let number of arrayOfNumbers" [value]="number">{{number}}</mat-option>
  </mat-select>
</mat-form-field>

</div>

但是所有不同*ngFor的值都相同。为什么会这样?而我该如何正确使用每个元素ID?

1 个答案:

答案 0 :(得分:0)

从定义属性绑定到[(ngModel)]指令的方式来看,differentArray的形式应为

differentArray = [
  { first: 0, second: 0, third: 0 },
  { first: 0, second: 0, third: 0 },
  { first: 0, second: 0, third: 0 }
]

工作示例:Stackblitz

更新

您可以将@Input()装饰器绑定到setter上,而不是直接将其插入父级,而直接在子级中初始化differentArray。但是无论您是在父母还是孩子中做,最重要的是要记住该对象将被引用推动。因此,对一个对象的任何更改也会影响其他对象。因此,您需要使用JSON.parse(JSON.stringify(obj))创建obj的深层克隆。尝试以下

parent.component.ts

export class ParentComponent {
  items = ['item1', 'item2', 'item3'];
  arrayOfNumbers = [1, 2, 3, 4, 5];
  differentArray = { first: 0, second: 0, third: 0 };

  constructor() {}
}

parent.component.html

<app-child [items]="items" [arrayOfNumbers]="arrayOfNumbers" [differentArray]="differentArray"></app-child>

child.component.ts

export class ChildComponent {
  _differentArray: Array<any> = [];

  @Input() items: Array<any> = [];
  @Input() arrayOfNumbers: Array<any> = [];
  
  @Input() set differentArray(obj: any) {
    this.items.forEach(item => 
      // notice the deep clone using `JSON.parse(JSON.stringify(obj)` here
      this._differentArray.push(JSON.parse(JSON.stringify(obj)))
    );
  }

  constructor() {}

  onSelection() {
    console.log('selected: ', this._differentArray);
  }
}

child.component.html

<div *ngFor="let item of items; let id=index;">
  <mat-form-field >
    <mat-select  [(ngModel)]="_differentArray[id].first"  (ngModelChange)="onSelection(id)">
      <mat-option *ngFor="let number of arrayOfNumbers" [value]="number">{{number}}</mat-option>
    </mat-select>
  </mat-form-field> 

  <mat-form-field>
    <mat-select  [(ngModel)]="_differentArray[id].second"  (ngModelChange)="onSelection(id)">
      <mat-option *ngFor="let number of arrayOfNumbers" [value]="number" >{{number}}</mat-option>
    </mat-select>
  </mat-form-field>

  <mat-form-field >
    <mat-select  [(ngModel)]="_differentArray[id].third"  (ngModelChange)="onSelection(id)">
      <mat-option *ngFor="let number of arrayOfNumbers" [value]="number">{{number}}</mat-option>
    </mat-select>
  </mat-form-field>
</div>

工作示例:Stackblitz