我正在使用工具提示指令,所以当我单击 <button>
时- 我动态注入(inject)并显示工具提示。
它运行良好,我确实看到了工具提示:
这是我用来在单击按钮时注入(inject)工具提示的代码:
@Directive({ selector: '[popover]'})
class Popover {
private _component: ComponentRef<>;
constructor(private _vcRef: ViewContainerRef, private _cfResolver: ComponentFactoryResolver,private elementRef: ElementRef) {
}
@HostListener('click')
toggle() {
if (!this._component) {
const componentFactory = this._cfResolver.resolveComponentFactory(PopoverWindow);
this._component = this._vcRef.createComponent(componentFactory);
} else {
this._vcRef.clear()
this._component.destroy();
this._component = null;
}
}
}
但我不希望屏幕上出现多个工具提示。
换句话说,在我注入(inject)工具提示之前 - 我想删除所有现有的工具提示 - 如果有的话。
问题:
如何在插入新工具提示之前“找到”所有现有工具提示并删除它们?
我知道我可以为每个类添加一个类,然后通过 removeNode 删除它们,但我想以 Angular 方式进行。
顺便说一句 - 我很乐意为组件找到通用解决方案,而不仅仅是指令。 (如果可能的话)。
最佳答案
一个明显的正确答案是使用一个服务,让你的弹出窗口注入(inject)这个服务,并在它们打开和关闭时注册到它,以了解当前是否打开了一个弹出窗口。
但让我们看看另一个不太明显的解决方案。这可能会让人不悦,但对于像这样的小事情,似乎确实是最简单和可读的方法。要在 Popover
类上使用静态属性:
@Directive({ selector: '[popover]'})
class Popover {
private static currentPopover: Popover;
private get active() {
return this === Popover.currentPopover;
}
private component: ComponentRef<any>;
constructor(
private vcRef: ViewContainerRef,
private cfResolver: ComponentFactoryResolver,
private elementRef: ElementRef
) {}
@HostListener('document:click')
onDocClick() {
if (this.active) {
this.close();
}
}
@HostListener('click', ['$event'])
toggle(event: MouseEvent) {
if (Popover.currentPopover && !this.active) {
Popover.currentPopover.close();
}
if (!this.active) {
this.open();
event.stopImmediatePropagation();
}
}
open() {
const componentFactory = this.cfResolver.resolveComponentFactory(PopoverWindow);
this.component = this.vcRef.createComponent(componentFactory);
Popover.currentPopover = this;
}
close() {
this.vcRef.clear()
this.component.destroy();
this.component = null;
Popover.currentPopover = undefined;
}
}
我还添加了一个文档点击监听器,因此当您点击其他任何地方时,它会关闭当前弹出窗口。
但是如果你愿意使用一个服务(未经测试的代码):
export class PopoverService {
private activePopover: Popover;
public setActive(popover: Popover): void {
if (this.activePopover) {
this.activePopover.close();
}
this.activePopover = popover;
}
public isActive(popover: Popover): boolean {
return popover === this.activePopover;
}
}
你的指令看起来像这样:
@Directive({ selector: '[popover]'})
class Popover {
private get active() {
return this.popoverService.isActive(this);
}
private component: ComponentRef<any>;
constructor(
private vcRef: ViewContainerRef,
private cfResolver: ComponentFactoryResolver,
private elementRef: ElementRef,
private popoverService: PopoverService
) {}
@HostListener('document:click')
onDocClick() {
if (this.active) {
this.close();
}
}
@HostListener('click', ['$event'])
toggle(event: MouseEvent) {
if (!this.active) {
this.open();
event.stopImmediatePropagation();
}
}
open() {
const componentFactory = this.cfResolver.resolveComponentFactory(PopoverWindow);
this.component = this.vcRef.createComponent(componentFactory);
this.popoverService.setActive(this);
}
close() {
this.vcRef.clear()
this.component.destroy();
this.component = null;
}
}
关于javascript - Angular - 如何删除所有其他现有指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44306496/