2017-10-10 61 views
2

我试图创建一个动态的形式在建筑行业用户,这将在每个层的基础作为分析的输入,针对建筑(任何数量的楼层的)例如:采用了棱角分明* ngFor与ngModel选择具有意想不到的结合

  1. 用户最初呈现为一个一层楼的形式,一种形式,但由于添加一个额外层的选项:

  2. 我们应该能够添加任何数量的额外层楼高的,并根据需要删除特定楼层。

方法

为了实现这一点,我试图利用* ngFor和迭代数组,其将在所述数据,使用ngModel结合到阵列中的每个对象。

component.html

<form *ngFor = "let storey of storeyData; let i = index; trackBy: trackByFn(i)"> 
    <md-select placeholder="Floor type" name ="floorTypeSelector{{i}}" [(ngModel)]="storeyData[i].floorTypes[0]"> 
     <md-option *ngFor="let floorType of floorTypes" [value]="floorType.value"> 
      {{floorType.viewValue}} 
     </md-option> 
    </md-select> 

<button md-raised-button (click)="incrementStoreyNumber()"> 
    <md-icon>library_add</md-icon> 
    Add storey 
</button> 

component.ts

export class FloorDetailsFormComponent implements OnInit { 

selectedFloorType = []; 
floorTypes = [ 
{value: 'concreteSlab', viewValue: 'Concrete slab'}, 
{value: 'suspendedTimber', viewValue: 'Suspended timber'}, 
{value: 'suspendedSlab', viewValue: 'Suspended slab'}, 
{value: 'wafflePod', viewValue: 'Waffle pod'} 
]; 

storeyData = [{floorTypes: [],floorAreas:[] }]; 
storeyDataTemplate = {floorTypes: [], floorAreas:[]}; 

incrementStoreyNumber(){ 
    this.storeyData.push(this.storeyDataTemplate); 
} 

trackByFn(index){ 
return index; 
} 
constructor() { } 
ngOnInit() { 
} 

问题

看来,第一两层结合它们的正确的变量,但是改变的选择的值第二层至第n层的任何一层都会改变其他层(第一层除外)。

搜索有关类似问题的其他职位后,我仍处于亏损状态,为什么发生这种情况。其他人遇到的一个问题是,对于* ngFor循环的每次迭代,元素的名称都没有被区分,但是查看我的console.log,我可以看到每个元素的名称都应该被索引。

我见过的一件有趣的事情是,如果我将typyData数组展开为typescript文件中的n层楼层,那么所有楼层都会绑定到它们自己的独立变量,并且所有楼层都是n层以后添加的+1有相同的问题。

我试过使用trackBy功能,但我似乎无法得到这个工作。当我试图扩展* ngFor范围时,我真的不了解底层的情况。也许这只是不好的做法?如果你能帮助我在这里,我会非常感激(即使其“哎,阅读了关于该”)

+0

退房这里我的答案,我认为这是对你的问题的解决方案:https://stackoverflow.com/questions/41265761/using-ngfor-with-ngmodel-dynamic-data-wrong-behaviour –

+0

非常感谢Stefan的回复。表单组的背景信息很有趣。我切换到使用[ngModelOptions] =“{standalone:true}”,并删除链接解决方案中建议的name属性,但它仍然表现出相同的行为。这是我之前尝试过的建议解决方案之一,但没有取得太大的成功。 – LNKX

+0

也在第二个ngfor上实现trackby。并将其更改为无参数版本:trackBy:trackByFn和trackByFn(item,index){return index} – Vega

回答

0

的问题是在这条线:

this.storeyData.push(this.storeyDataTemplate); 

当您添加storeyDataTemplate对于storeyData,每次推送时都会绑定同一个对象,并且ngFor跟踪同一个对象。如果您更改为:

this.storeyData.push({floorTypes: [], floorAreas:[]}); 

它会工作。

DEMO

+1

就是这样!你是一个天才:)非常感谢你花时间去了解这个问题。该修复解释了我所看到的所有行为,并为我介绍了ngFor的工作原理。只要我有足够的声望(我只有8 ...)我会热情地赞扬这一点:) – LNKX