我正在try 重构一小段HTML,以便从*ngFor指令迁移到新的@For指令

    <mat-menu #clientsMenu="matMenu">
      <ng-container *ngFor="let item of clientMenu | keyvalue">
        <button mat-menu-item [matMenuTriggerFor]="sub_menu">{{ item.key }}</button>
        <mat-menu #sub_menu="matMenu" class="menu">
          <button *ngFor="let p of item.value" mat-menu-item (click)='changePlanta(p)'>
            <div>
              <span style="padding-right:10px;">{{p.nome_planta}}</span>
              <span>{{p.id_planta}}</span>
            </div>
          </button>
        </mat-menu>
      </ng-container>
    </mat-menu>

ClientMenu不是一个数组,而是一个对象,因此在这个早期版本中,使用KeyValue管道来迭代键(字符串)和值(对象数组).

我试着保持同样的逻辑:

    <mat-menu #clientsMenu="matMenu">
      @for (client of clientMenu | keyvalue; track client){
        <button mat-menu-item [matMenuTriggerFor]="sub_menu">{{ client.key }}</button>
        <mat-menu #sub_menu="matMenu" class="menu">
          @for (planta of client.value; track planta){
            <button mat-menu-item (click)='changePlanta(planta)'>
              <div>
                <span style="padding-right:10px;">{{planta.nome_planta}}</span>
                <span>{{planta.id_planta}}</span>
              </div>
            </button>
          }
        </mat-menu>
      }
    </mat-menu>

但是我在"client.value"中得到了error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.,它应该是一个array.

类代码如下:

 public clientMenu = {};

 async ngOnInit() {

    this.routeSubscription = this.routeGuards.authorized.subscribe(async (authorized) => {
      if (authorized){
        if (this.user.isUgm()){
          this.user.plantas = await this.http.centralGet('get_plantas');
    
          new Set(this.user.plantas.map(p=>p.nome_cliente)).forEach(c=>{
            this.clientMenu[`${c}`]= this.user.plantas.filter(p=>p.nome_cliente == c).sort((p1, p2) => p1.nome_planta.localeCompare(p2.nome_planta))
          })
          console.log('this.clientMenu', this.clientMenu)
        };
      };
    });
  };

clientMenu被记录为这样的东西(简化):

{ client1: [{id_planta: 1, nome_planta: 'planta1'}, {id_planta: 2, nome_planta: 'planta2'}], client2: [...same logic...] }

在这种情况下如何使用@for?

推荐答案

使用track client.key

例如:

@for(keypar of client|keyvalue;track keypar.key)
{
  <div>
  @for(item of keypar.value;let i=$index;track i)
  {
  <span>{{item}}</span>
  }
</div>

什么时候

client={one:['one','one one'],two:['two','two 2','two 3']}

顺便说一句,使用带唯一属性的Track或"Item"(或自己的$index)比使用自己的"Item"要好

Update关于严格模式

当我们定义一些类似的东西

public clientMenu = {};

Angular 在严格的模式Angular 理解是类型的"从不"

We need give it some "type". We can do it with an interface, 例如:

interface CustomClient {
  value: {
    [key:string]: any
  }
}
//and use
client:CustomClient={}

或直接

client:{[key:string]: any}={}

Angular相关问答推荐

Angular 信号效果,try 重置表单并获取在计算或效果中不允许写入信号"

如何在Angular 17中使用Angular—calendum?

有没有一种方法用timeout()操作符创建计数器,用于超时一个观察对象?

Angular 环境本地无文件替换

如何将Angular 服务包含在延迟加载的独立组件路由中?

弯管记忆

执行ng generate environments时出错时需要合集和原理图

PrimeNG 避免在同一位置使用不同键的 cogo toast 重叠

应该显示在表格中的嵌套循环

个人修改 Angular CLI - 创建新应用

Angular 2模板驱动表单访问组件中的ngForm

将数组传递给 URLSearchParams,同时使用 http 调用获取请求

如何重新加载当前页面?

Angular 4 - 在下拉列表中 Select 默认值 [Reactive Forms]

带有 Angular 的 Font Awesome 5

在 Angular 中动态设置样式

@angular/platform-b​​rowser 与 @angular/platform-b​​rowser-dynamic

Angular2延迟加载模块错误'找不到模块'

如何在功能模块层次 struct 中使用 .forRoot()

缺少带有Angular的语言环境XXX的语言环境数据