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
相关产品推荐
相关产品推荐

