【问题标题】:how to do ngFor inside ngFor dynamically in angular 8?如何在 Angular 8 中动态地在 ngFor 中执行 ngFor?
【发布时间】:2020-02-01 19:20:12
【问题描述】:

嗨,我想要实现的是 ngFor 在 ngFor 内部具有动态值,这可能吗?我也尝试在其中使用 ngModel,但没有成功。这就是我所做的:

在我的 home.component.ts 中:

import { Component, OnInit } from '@angular/core';
import {CdkDragDrop, moveItemInArray} from '@angular/cdk/drag-drop';

export interface Condition {
  value: string;
  viewValue: string;
}

export interface ListProduk {
  value: string;
  viewValue: string;
}

export interface DragBox {
  value: string;
  viewValue: string;
}

export interface ListModel {
  value: string;
  viewValue: string;
  single_item: string;
}

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})

export class HomeComponent implements OnInit {

  conditions: Condition[] = [
    { value: 'if', viewValue: 'IF' },
    { value: 'else', viewValue: 'ELSE' },
    { value: 'then', viewValue: 'THEN' },
    { value: 'if else', viewValue: 'IF ELSE' },
    { value: 'or', viewValue: 'OR' },
    { value: 'and', viewValue: 'AND' }
  ];

  listProduks: ListProduk[] = [
    { value: 'mcm-508', viewValue: 'MCM-508' },
    { value: 'bl-100 pl', viewValue: 'BL-100 PL' },
    { value: 'bl-150 bl', viewValue: 'BL-150 BR' },
    { value: 'bl-302gs', viewValue: 'BL-302GS' },
    { value: 'bl-52gl', viewValue: 'BL-52GL' }
  ];

  listModels: ListModel[] = [
    { value: 'conditions', viewValue: 'Condition', single_item:'condition' },
    { value: 'listProduks', viewValue: 'List Produk', single_item:'listProduk' },
  ]

  constructor() { }

  ngOnInit() {
  }

  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.listModels, event.previousIndex, event.currentIndex);
  }

}

然后这是我的 home.component.html :

<p>home works!</p>

<div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let listModel of listModels" cdkDrag>
        <mat-form-field>
            <mat-label>Pick {{listModel.value}} :</mat-label>
            <mat-select>
                <mat-option *ngFor="let {{listModel.single_item}} of {{listModel.value}}" [value]="{{listModel.single_item}}.value">
                    test
                </mat-option>
            </mat-select>
        </mat-form-field>
        <div>
            <i class="material-icons">
                arrow_right_alt
            </i>
        </div>
    </div>
</div>

我尝试动态循环 mat-select,因为我希望它循环一个具有不同名称的数组,我需要 listModel 数组中的值打印到 mat-select 内的 *ngFor。这是哪一行:

            <mat-option *ngFor="let {{listModel.single_item}} of {{listModel.value}}" [value]="{{listModel.single_item}}.value">
                test
            </mat-option>

如何正确地做到这一点?

更新的问题用 Ahmed 评论更新我的代码后,我的 Html 看起来像这样:

<p>home works!</p>

<div cdkDropList cdkDropListOrientation="horizontal" class="example-list" (cdkDropListDropped)="drop($event)">
    <div class="example-box" *ngFor="let listModel of listModels" cdkDrag>
        <mat-form-field>
            <mat-label>Pick {{listModel.value}} :</mat-label>
            <mat-select>
                <mat-option *ngFor="let a of listModel.value" [value]="a.value">
                    {{a.viewValue}}
                </mat-option>
            </mat-select>
        </mat-form-field>
        <div>
            <i class="material-icons">
                arrow_right_alt
            </i>
        </div>
    </div>
</div>

这给了我这样的错误:

错误错误:找不到不同的支持对象“条件” 输入“字符串”。 NgFor 仅支持绑定到 Iterables,例如 数组。

我错过了什么?

【问题讨论】:

  • 我之前回答过类似的问题,这就是递归原理。这是链接,它可能会有所帮助:stackoverflow.com/questions/58061294/…
  • 第二个循环有问题,应该使用不带括号的循环。 &lt;mat-option *ngFor="subitem of listModel.value" [value]="subitem.value"&gt; test &lt;/mat-option&gt;
  • @AhmedEl-sayed 在我尝试之后,我收到了这样的错误:错误错误:找不到“字符串”类型的不同支持对象“条件”。 NgFor 只支持绑定到 Arrays 等 Iterables。
  • @KeVin ,这意味着您的响应数组不是有效的 JSON 值,检查“listModel.value”的值
  • 值是条件,当我用“条件”字符串替换listModel.value时没有什么不同,它可以工作,但是当用listModel.value打印时,为什么它说它是一个字符串?

标签: arrays angular angular-material ngfor


【解决方案1】:

您可以使用返回正确数组的函数来显示它。我们在模板中调用它。 小心,我绝不建议在模板中调用函数,如果这是可能的话。这会严重影响应用程序的性能。但是,如果您在此页面上没有太多内容,那么使用它是非常安全的。所以我建议如下:

<div *ngFor="let value of getList(listModel.value)">

并且该函数将返回正确的数组:

getList(value) {
  return this[value]
}

您还可以对模型进行轻微更改,并将带有正确数组的数组的可选参数传递给对象本身。你可以在OnInit

ngOnInit() {
  this.listModels.forEach(x => {
    x.customArray = this[x.value]
  })
}

并在*ngFor 中像正常迭代一样使用它:

<div *ngFor="let value of listModel.customArray">

这是一个STACKBLITZ,有两个选项

【讨论】:

  • 谢谢它的工作!我选择第二种方式,修改模型。并感谢stackblitz,这是很大的帮助。我发现了写成 customArray?:any[] 的模型属性有“?”里面有问号,“?”是什么意思?那里?
  • @KeVin 不错的选择! :) customArray? 表示它是一个可选属性,因此如果您要向ListModel 键入一些对象,如果没有该属性,您的编译器就不会抱怨它丢失了。我也很懒,在那里使用了any[]。你真的应该做类似...customArray?: ListProduk[] | DragBox[] | Condition [] 这意味着customArray 是这些模型之一。
  • 虽然我也看到,所有这些模型都是相同的,所以理论上你可以只拥有一个涵盖所有三个的模型,而不是拥有三个相同的模型,只是名称不同。但这只是一个细节:)
猜你喜欢
  • 1970-01-01
  • 2020-03-08
  • 2020-03-01
  • 2020-08-27
  • 2017-09-20
  • 2016-09-10
  • 2016-04-06
  • 1970-01-01
相关资源
最近更新 更多