我正在尝试为建筑行业的用户创建一个动态表单,它将逐层分析建筑物(任意层数)的输入:

  • 用户最初会看到一个单层表单,但可以选择添加额外的楼层:
  • 我们应该能够添加任意数量的额外楼层,并根据需要删除特定楼层。

  • 方法

    为了实现这一点,我试图利用 *ngFor 并迭代一个将接收数据的数组,使用 ngModel 绑定(bind)到数组中的每个对象。

    组件.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>
    

    组件.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() {
    }
    

    问题

    似乎前两层正确绑定(bind)到它们的变量,但是更改任何 2 层到第 n 层的选定值将更改所有其他层(第一层除外)。

    在搜索了有关类似问题的其他帖子后,我仍然不知道为什么会发生这种情况。其他人遇到的一个问题是,*ngFor 循环的每次迭代都没有区分元素的名称,但是查看我的 console.log,我可以看到每个元素的名称都被编入索引。

    我看到的一件有趣的事情是,如果我在 typescript 文件中将 storeyData 数组扩展到 n 层的长度,那么直到 n 层的所有层都应该绑定(bind)到它们自己的自变量,并且所有 n+1 层都是后来补充也有同样的问题。

    我试过使用 trackBy 功能,但我似乎也无法让它工作。当我试图动态扩展 *ngFor 范围时,我真的不了解引擎盖下发生了什么。也许这只是不好的做法?如果你能在这里帮助我,我将不胜感激(即使是“嘿,仔细阅读”)

    最佳答案

    问题出在这一行:

    this.storeyData.push(this.storeyDataTemplate);
    

    当您将 storeyDataTemplate 添加到 storeyData 时,每次推送时都会绑定(bind)同一个对象,而 ngFor 会跟踪同一个对象。如果您更改为:
    this.storeyData.push({floorTypes: [], floorAreas:[]});
    

    它会起作用。

    DEMO

    关于javascript - Angular *ngFor with ngModel using Select 具有意外绑定(bind),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46658597/

    10-13 04:22