2 way binding ngmodel to a 2d array is giving undefined when dynamically populating the array

huangapple go评论77阅读模式
英文:

2 way binding ngmodel to a 2d array is giving undefined when dynamically populating the array

问题

我想使用 [(ngModel)] 绑定到一个二维布尔数组,因为我的 HTML 中有嵌套的 ngFor 循环。我想动态填充这个数组,因为数据将来自数据库,但由于 HTML 在数组填充之前开始访问数据,所以会导致未定义错误。

**HTML 代码**

```html
<div *ngFor="let item of DriveDateSlots;let indexOfDate = index">
    <div *ngFor="let Slotitem of getTimeSlotDateWise(item.driveSlotDate);let indexOfSlot = index">
        <mat-slide-toggle [(ngModel)]="isSlotHidden[indexOfDate][indexOfSlot]">隐藏</mat-slide-toggle>
    </div>
</div> 

声明

isSlotHidden: boolean[][] = [[]];
DriveSlot: any = [];

TypeScript 代码

GetAllDriveSlots(): any {
    this.DriveSlot = [];
    this.masterservice.GetAllDriveSlotDetail(this.DriveID).subscribe((response: any) => {
        this.DriveSlot = response;
        let k = 0;
        const uniqueDates = [...new Set(this.DriveSlot.map( obj => obj.driveSlotDate ))];
        for(let i=0;i<uniqueDates.length;i++)
        {
            let j=0;
            while(k < this.DriveSlot.length && this.DriveSlot[k].driveSlotDate == uniqueDates[i])
            {
                this.isSlotHidden[i][j]= false;
                j++;
                k++;
            }
        }
    },
    (error: any) => {
        console.log("错误");
    })
}

这个 TypeScript 函数在 ngOnInit 中调用。我不确定如何解决这个问题,因为 HTML 不会等待 TypeScript 函数完成。目前,我只是用 false 填充了二维数组,但将来我计划从数据库获取数据来填充它。

我尝试在声明时使用虚拟数据进行初始化,它可以正常工作,但由于行数和列数未知,这可能会在将来引发一些问题。


<details>
<summary>英文:</summary>

I want to use [(ngModel)] bound to a 2d boolean array as I have a nested ngFor loop in the html. I want to populate this array dynamically as data will be coming from database but as the html starts to access the data before the array has been populated, it ends up giving me an undefined error.

**Html Code**

<div *ngFor="let item of DriveDateSlots;let indexOfDate = index">
<div *ngFor="let Slotitem of getTimeSlotDateWise(item.driveSlotDate);let indexOfSlot = index">
<mat-slide-toggle [(ngModel)]="isSlotHidden[indexOfDate][indexOfSlot]">Hide</mat-slide-toggle>
</div>
</div>


**Declarations**

isSlotHidden: boolean[][] = [[]];
DriveSlot: any = [];


**ts code**

GetAllDriveSlots(): any {
this.DriveSlot = [];
this.masterservice.GetAllDriveSlotDetail(this.DriveID).subscribe((response: any) => {
this.DriveSlot = response;
let k = 0;
const uniqueDates = [...new Set(this.DriveSlot.map( obj => obj.driveSlotDate ))];
for(let i=0;i<uniqueDates.length;i++)
{
let j=0;
while(k < this.DriveSlot.length && this.DriveSlot[k].driveSlotDate == uniqueDates[i])
{
this.isSlotHidden[i][j]= false;
j++;
k++;
}
}
},
(error: any) => {
console.log("Error");
})
}


the ts function is called inside ngOnInit. I am not sure how I can resolve this as the html does not wait for the ts function to complete. Currently I am just populating the 2d array with false but I plan on getting data from database to populate it in the future.

I have tried initialising it with dummy data during declaration and it worked fine but since the number of rows and columns are not known. This can definitely cause some trouble in the future.

</details>


# 答案1
**得分**: 1

你可以尝试不将DriveSlot初始化为空数组:

```typescript
DriveSlot: any = [];

而是只声明它:

DriveSlot: any;

在 HTML 文件中,将ngIf应用于ngFor的容器:

<div *ngIf="DriveSlot">
    <div *ngFor="let item of DriveDateSlots; let indexOfDate = index">
        <div *ngFor="let Slotitem of getTimeSlotDateWise(item.driveSlotDate); let indexOfSlot = index">
            <mat-slide-toggle [(ngModel)]="isSlotHidden[indexOfDate][indexOfSlot]">Hide</mat-slide-toggle>
        </div>
    </div>
</div>

使用这种方法,只有在订阅结束时才渲染HTML代码,并且您使用响应来初始化DriveSlot

英文:

You can try not to initialize DriveSlot as an empty array:

DriveSlot: any = [];

.. instead, just declare it:

DriveSlot: any;

And in the html file, use tthe ngIf on a container of tthe ngFor:

&lt;div *ngIf=&quot;DriveSlot&quot;&gt;
    &lt;div *ngFor=&quot;let item of DriveDateSlots;let indexOfDate = index&quot;&gt;
        &lt;div *ngFor=&quot;let Slotitem of getTimeSlotDateWise(item.driveSlotDate);let indexOfSlot = index&quot;&gt;
            &lt;mat-slide-toggle [(ngModel)]=&quot;isSlotHidden[indexOfDate][indexOfSlot]&quot;&gt;Hide&lt;/mat-slide-toggle&gt;
        &lt;/div&gt;
    &lt;/div&gt; 
&lt;/div&gt; 

With his aproach, you only render the html code when the suscription ends and you initialize DriveSlot with the response

huangapple
  • 本文由 发表于 2023年6月27日 19:13:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76564279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定