为什么部分Angular指令需以*开头?以matHeaderCellDef与matColumnDef为例
这个问题问得特别好!其实Angular里带*的指令和不带的,本质是结构型指令和属性型指令的区别,咱们掰开揉碎了说:
先搞懂*的本质:语法糖简化模板写法
Angular里的*是个语法糖,专门用来简化<ng-template>的编写。结构型指令需要基于模板来操作DOM,直接写<ng-template>会有点繁琐,用*就能把当前元素直接“包裹”成模板,让代码更简洁。
比如你例子里的*matCellDef="let element",展开后其实是下面这样的:
<ng-template matCellDef let-element> <td mat-cell> {{element.position}} </td> </ng-template>
两种指令的核心区别
1. 带*的结构型指令:操控DOM结构
这类指令的核心能力是改变DOM的结构——比如重复渲染元素、添加/删除元素、切换元素的显示状态。
你例子里的*matHeaderCellDef和*matCellDef就属于这类:它们是Angular Material表格的结构型指令,负责定义表头单元格和数据单元格的模板。Angular会根据表格的数据源,循环渲染这些模板,把每个数据项绑定到模板变量(比如element),最终生成对应的<th>和<td>元素。
2. 不带*的属性型指令:增强元素功能
这类指令不会修改DOM结构,只是给现有元素添加额外的行为、样式或元数据。
比如matColumnDef="position",它只是给<ng-container>标记了一个列的唯一标识,告诉Angular Material“这个容器是对应position列的定义”。它不会创建新元素,也不会删除元素,只是给这个容器赋予了表格列的相关配置和行为。
一句话总结
带*的是结构型指令,管的是“DOM元素要不要生成、生成多少个”;不带*的是属性型指令,管的是“现有元素有什么功能、怎么表现”。Angular用*语法糖帮咱们省掉了写<ng-template>的麻烦,让代码更清爽。
内容的提问来源于stack exchange,提问作者Roger Xi

