将属性指令应用于每个项目的ngForTemplate

问题描述 投票:0回答:1

我正在构建一个独立组件,它接收要使用 ngFor 渲染的对象集合。用于渲染这些对象的 templateRef 是通过 ContentChild 获取的。

      <ng-template
        ngFor
        let-item
        [ngForOf]="items"
        [ngForTemplate]="template"
        [ngForTrackBy]="trackByFunction"
      >
      </ng-template>

用法如下:

<my-component [items]="items">
  <ng-template let-item>
    {{item.name}}
  </ng-template>
</my-component>

我想向每个项目添加一个指令,该指令将执行一些简单的属性操作,例如添加类、保存维度。这个想法是,将使用该组件代替 ngFor 来执行更高级的逻辑。我想避免在使用端将指令添加到 html 中。我也希望能够从 MyComponent 访问该指令。

我该怎么做?

编辑: 即使我将指令放在使用端,我仍然需要一种方法来以某种方式查询渲染的项目。到目前为止,我发现 ContentChild/ViewChild 和

read
的组合没有任何帮助。

angular
1个回答
0
投票

典型的是将模板作为组件中的输入传递,例如

@Component({
  selector: 'list-items',
  standalone: true,
  imports: [CommonModule],
  template: `
  @if(template)
  {
    @for (item of items;track $index)
    {
      <ng-container *ngTemplateOutlet="template;context:{$implicit:item}"></ng-container>
    }
  }
  `,
})
export class ListItems {
  @Input() items: any[] = [];
  @Input()template!:TemplateRef<any>;
}

你用喜欢

<list-items [items]="items" [template]="tempalte"></list-items>
<ng-template #tempalte let-item>
    <div style="border:1px solid silver;padding:.5rem;margin:.5rem">
      <p>Id:{{item.id}}</p>
      <p>Name:{{item.name}}</p>
    </div>
</ng-template>

如果我们可以像“ng-content”一样将模板放入其中,我们就可以使用ContentChild获取模板

@Component({
  selector: 'list-items-content',
  standalone: true,
  imports: [CommonModule],
  template: `
  @if(templateRef)
  {
    @for (item of items;track $index)
    {
      <ng-container *ngTemplateOutlet="templateRef;context:{$implicit:item}"></ng-container>
    }
  }
  <ng-content></ng-content>
  `,
})
export class ListItemsContent {
  @Input() items: any[] = [];
  @ContentChild(TemplateRef) template!: any;
  get templateRef() {
    return this.template || null;
  }
}

你用喜欢

<list-items-content [items]="items">
  <ng-template let-item>
    <div style="border:1px solid silver;padding:.5rem;margin:.5rem">
      <p>Id:{{item.id}}</p>
      <p>Name:{{item.name}}</p>
    </div>
  </ng-template>
</list-items-content>

a stackblitz 具有两个选项

© www.soinside.com 2019 - 2024. All rights reserved.