【发布时间】:2019-05-26 03:16:39
【问题描述】:
我正在寻找一种简单的方法来覆盖开箱即用提供的指令的行为,例如ngIf
所以我可以创建一个子指令并扩展行为,然后声明为原生指令。
P.S.:我知道覆盖标准功能是非常糟糕的做法,但我这样做只是为了学习/研究目的。
【问题讨论】:
我正在寻找一种简单的方法来覆盖开箱即用提供的指令的行为,例如ngIf
所以我可以创建一个子指令并扩展行为,然后声明为原生指令。
P.S.:我知道覆盖标准功能是非常糟糕的做法,但我这样做只是为了学习/研究目的。
【问题讨论】:
您可以考虑编写自己的 ngIf,例如 myIf
import { Directive, Input, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[myIf]'
})
export class MyIfDirective {
constructor(
private element: ElementRef,
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef
) {
}
@Input()
set myIf(val) {
if(val) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
}
然后
<div *myIf="isVisible">
Hi there!
</div>
或者这会有所帮助
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import {NgIf} from "@angular/common"
@Directive({
selector: '[ngIf][myNgIf]'
})
export class myNgIf extends NgIf {
@Input() myNgIf: boolean;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
super(viewContainer, templateRef);
}
@Input()
set ngIf(val) {
if (val) {
...
} else {
this.viewContainer.clear();
}
}
【讨论】:
如果您的目标是扩展已经提供的行为,则可以很容易地做到这一点。您只需要创建自定义指令并使用选择器,例如 [ngIf]。
但是您使用指令的元素仍然与原始ngIf 相关联。所以你不会得到一个好的和干净的解决方案来摆脱原来的行为。
你可以在stackblitz看到一个例子
要真正覆盖这些解决方案,它们可能以某种方式可用而不是破解
自行重新实现/扩展指令并将其导入模块而不是原来的模块中
ngIf 的情况下,这意味着创建自定义CommonModule,它会从角度核心公开此指令使用 angular 的“调整”叉
使用正则表达式查找所需指令的所有匹配项(例如ngIf)并将其替换为您可以在选择器中轻松使用的自定义名称([myNgIf])
【讨论】: