You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular5可复用SortedList组件问题:如何传递自定义项模板?

解决Angular5可复用SortedList组件的动态模板问题

你说得没错,问题就出在静态内容投影的局限性上——原来的<ng-content>只会把你传入的<ACustomItem>渲染一次,不会跟着*ngFor循环去动态绑定每个item。要实现这种"动态模板复用",确实需要结合ng-template和ngTemplateOutlet来做,下面是具体的修复步骤:

1. 修改父组件(ListContainer)的模板用法

把你传入的<ACustomItem>包裹在<ng-template>里,用let-item声明一个模板输入变量,用来接收后续传递的列表项:

<div class='list-container'>
  <SortedList [items]='getListItems()' [categories]='getSortCategories()'>
    <!-- 用ng-template包裹自定义模板,let-item接收循环的item -->
    <ng-template let-item>
      <ACustomItem [item]='item'></ACustomItem>
    </ng-template>
  </SortedList>
</div>

2. 在SortedList组件中获取父组件传递的模板

在SortedListComponent的TS文件里,通过@ContentChild装饰器获取父组件传入的<ng-template>引用:

import { Component, Input, ContentChild, TemplateRef } from '@angular/core';

@Component({
  selector: 'SortedList',
  templateUrl: './sorted-list.component.html'
})
export class SortedListComponent {
  @Input() items: any[];
  @Input() categories: any[];
  @Input() title: string;
  selectedCategory: any;

  // 捕获父组件传入的模板
  @ContentChild(TemplateRef) itemTemplate: TemplateRef<any>;

  onCategoryChange(event: any) {
    // 这里保留你的排序逻辑(注意:Angular5原生没有orderBy管道,需要自定义或在组件内处理排序)
  }
}

3. 修改SortedList组件的HTML模板

把原来的<ng-content>替换成ngTemplateOutlet,通过上下文把当前循环的item传递给模板:

<div class='sorted-list'>
  <div class='sorted-list__header'>
    <div class='sorted-list__header-title'>{{title}}</div>
    <select [(ngModel)]='selectedCategory' (ngModelChange)='onCategoryChange($event)'>
      <!-- 建议绑定整个category对象,方便后续获取排序属性 -->
      <option *ngFor='let category of categories' [ngValue]='category'>{{category.name}}</option>
    </select>
  </div>
  <div class='sorted-list__body'>
    <div *ngFor="let item of items | orderBy: selectedCategory?.id">
      <!-- 用ngTemplateOutlet渲染每个item的模板,通过$implicit传递item -->
      <ng-container *ngTemplateOutlet="itemTemplate; context: { $implicit: item }"></ng-container>
    </div>
  </div>
</div>

关键细节说明

  • $implicit的作用:它是模板上下文的默认变量,当你在<ng-template>里写let-item时,Angular会自动把context中的$implicit值赋值给item变量。
  • 关于orderBy管道:Angular从版本2开始就移除了原生的orderBy管道,所以你需要自己实现一个自定义管道,或者在组件的onCategoryChange方法里直接对items数组进行排序处理。
  • selectedCategory的绑定:把<option>的ngValue从category.id改成整个category对象,这样可以更方便地获取排序所需的属性(比如selectedCategory.id)。

这样修改后,你的SortedList组件就能正确遍历每个列表项,把每个item传递给父组件提供的自定义模板,实现真正的可复用性啦!

内容的提问来源于stack exchange,提问作者mtx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:26:34