gpt4 book ai didi

javascript - Angular - 如何删除所有其他现有指令?

转载 作者:太空狗 更新时间:2023-10-29 17:54:27 32 4
gpt4 key购买 nike

我正在使用工具提示指令,所以当我单击 <button> 时- 我动态注入(inject)并显示工具提示。

它运行良好,我确实看到了工具提示:

enter image description here

这是我用来在单击按钮时注入(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 方式进行。

Full Plunker

顺便说一句 - 我很乐意为组件找到通用解决方案,而不仅仅是指令。 (如果可能的话)。

最佳答案

一个明显的正确答案是使用一个服务,让你的弹出窗口注入(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;
}
}

我还添加了一个文档点击监听器,因此当您点击其他任何地方时,它会关闭当前弹出窗口。

plunkr

但是如果你愿意使用一个服务(未经测试的代码):

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/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com