写这篇博客的原有:虽然Angular官网有提到指令的使用,以及相关Ref的使用,但是对相关Ref并没有做出详细的解释,也没有提供相关的详细文档。
明确 *ngIf 是一个结构型指令,需要 @Directive 修饰器
2022/11/11 更新
注:前提知识
Angular官方并没有给出 simpleChange 的用法
let change = changes ["expressionResult"]; 是获取到某个属性的change状态
@Directive({
selector: '[fuckIf]'
})
export class FuckStructureDirective{
constructor(private container:ViewContainerRef, private temple:TemplateRef<Object>) {
@Input("fuckIf") expressionResult:boolean;
ngOnchanges(changes:{ [property:string]:SimpleChange })
{
let change = changes ["expressionResult"];// 看看清楚啊 change和changes
if (!change.isFirstChange() && !change.currentValue)
{
this.container.clear();
}
else if (change.currentValue)
{
this.container.createEmbeddedView(this.template)
}
}
}
}
解释一下这段代码:
ViewContainerRef 对象用于管理视图容器,是视图的集合。视图就是 包含指令,绑定,表达式的HTML元素区域。
视图的创建通过ViewContainerRef类提供的各种API来实现。如下图:
手写 *ngIf时候用到两个方法:
createEmbeddedView()向用户显示 ng-temple 元素的内容,然后使用 clear( ) 来删除。
那么:
container:ViewContainerRef 代表 ng-temple元素在 HTML 文档中占用的地方
temple:TemplateRef<Object> 代表 ng-temple 元素的内容
注:changes:{[propKey:string]:SimpleChange}是什么? 索引签名,用于限制对象属性类型 一文读懂TS索引签名 - Yune_Neko - 博客园
意思是 用 string 去索引,得到一个 SimpleChange类型对象;
此class会在初始化期间,调用 ngOnChanges方法,他接受SimpleChange 对象,根据表达式当前的值来判断是否显示当前的内容。
注:* 前缀是Angular的简洁语法
星号(*)前缀
星号是一个用来简化更复杂语法的“语法糖”。 从内部实现来说,Angular 把 *ngIf 属性 翻译成一个 元素 并用它来包裹宿主元素,代码如下:ngIf 指令
<div *ngIf="hero" class="name">{{hero.name}}</div>
等价于
<ng-template [ngIf]="hero"> <div class="name">{{hero.name}}</div> </ng-template>