用ng进行角度选择更改第一选择会影响第二选择

时间:2018-12-07 15:21:35

标签: angular typescript

我正在尝试使用*ngFor构建由多个<select>(其中3x个)组成的捆绑包,但我发现了另一个SO来使我前进。但是,我现在遇到的问题是它们不是独立的,如果我更改第一个选择,它也反映了第二个选择的更改(而不是第三个选择)。值得一提的是,所有Select都有相同的列表,这就是为什么第一个影响第二个的原因,但是我真的希望它们独立。

哦,我目前正在使用Angular 5,所以它不是最新的。

这是我必须使用*ngFor

进行3 Select循环的代码
<div class="col-sm-3" *ngFor="let groupField of selectedGroupingFields; let i = index;">
<select class="form-control col-sm-6" name="groupField{{i}}" [(ngModel)]="selectedGroupingFields[i]" (ngModelChange)="groupByFieldName($event, i)">
    <option value=""></option>
    <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
</select>

集合的结构如下

selectedGroupingFields: string[] = ['', '', ''];    
columnDefinitions = [
  { id: 'title', name: 'Title'}, 
  { id: 'duration', name: 'Duration'},
  { id: 'percentComplete', name: '% Complete'},
  { id: 'start', name: 'Start'},
  { id: 'Finish', name: 'Finish'},
  { id: 'cost', name: 'Cost'},
  { id: 'effortDriven', name: 'Effort-Driven'}
];

为演示该问题,我做了一个通过单击按钮触发的小功能

changeFirstGroupBy() {
  this.selectedGroupingFields[0] = 'title';
}

当我单击按钮并执行该功能时,它将更改前2个Select ...为什么?

因此,我进行了更多测试,并决定通过逐个复制1来分别创建每个Select,并像这样删除*ngFor上的<div>

<div class="col-sm-3">
    <select class="form-control col-sm-6" name="groupField1" [(ngModel)]="selectedGroupingFields[0]" (ngModelChange)="groupByFieldName($event, i)">
        <option value=""></option>
        <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
    </select>
</div>
<div class="col-sm-3">
    <select class="form-control col-sm-6" name="groupField2" [(ngModel)]="selectedGroupingFields[1]" (ngModelChange)="groupByFieldName($event, i)">
        <option value=""></option>
        <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
    </select>
</div>
<div class="col-sm-3">
    <select class="form-control col-sm-6" name="groupField3" [(ngModel)]="selectedGroupingFields[2]" (ngModelChange)="groupByFieldName($event, i)">
        <option value=""></option>
        <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
    </select>
</div>

,那行得通!但为什么?那应该是与*ngFor完全相同的代码。另外,如果我更改了最后一个选择(请参见演示),它也会影响第二个选择,这很奇怪,但是当我手动创建所有3个选择时它确实可以正常工作。

这是问题的动画GIF

enter image description here

编辑

忘记了,我还尝试将2种方式的绑定更改为1种方式,它具有相同的效果[ngModel]="selectedGroupingFields[i]"

回答

这正在工作,并用于我的Angular-Slickgrid的开放源代码库,这是我使用此答案的demo。谢谢:)

2 个答案:

答案 0 :(得分:1)

嘿,您正在使用两种方式的数据绑定

[(ngModel)]=selectedGroupingFields[i]

要使其按预期工作,可以使其如下:

<div class="col-sm-3" *ngFor="let groupField of selectedGroupingFields; let i = index;">
 <select class="form-control col-sm-6" name="groupField{{i}}" [ngModel]="selectedGroupingFields[i]" (ngModelChange)="groupByFieldName($event, i)">
  <option value=""></option>
  <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}} 
 </option>
</select>

请在此处检查工作示例:Link

答案 1 :(得分:1)

您可以通过为trackBy指令提供ngFor函数来解决此问题:

<div ... *ngFor="let groupField of selectedGroupingFields; let i = index; trackBy: trackByFn">
  <select ... name="groupField{{i}}" [(ngModel)]="selectedGroupingFields[i]" (ngModelChange)="groupByFieldName($event, i)">
    <option value=""></option>
    <option [ngValue]="field.id" *ngFor="let field of columnDefinitions">{{field.name}}</option>
  </select>
</div>

其中trackByFn返回项index

trackByFn(index, item) {
  return index;
}

有关演示,请参见Android: How to use the Html.TagHandler?