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

标签 javascript angular angular-directive

我正在使用工具提示指令,所以当我单击 <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/

相关文章:

angular - 当应用于 Angular 中的嵌套网格时,Mat-Table 数据源被覆盖

javascript - Ionic 2内部函数和外部函数

javascript - jQuery $.extend[ing] 带有返回空函数参数的函数

javascript - 如何将 redux 状态传递给子路由?

javascript - 从数据库中删除记录而不刷新

angular - 在 Spring Boot 中从 Angular 7 的请求接收空授权 header ,但 Postman 工作正常

javascript - jQuery 克隆和附加功能无法按 AngularJS 指令中的预期工作

javascript - 无法使用 Angular 将 bool 值传递给指令

angular - 使用 ngFor 创建不同的元素类型

javascript - 如何获取数组中数字的最大出现次数