Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 角度-如何删除所有其他现有指令?_Javascript_Angular_Angular Directive - Fatal编程技术网

Javascript 角度-如何删除所有其他现有指令?

Javascript 角度-如何删除所有其他现有指令?,javascript,angular,angular-directive,Javascript,Angular,Angular Directive,我使用的是工具提示指令,因此当我单击一个-时,我会动态地插入并显示工具提示 它确实工作得很好,我确实看到了工具提示: 这是我用来在单击按钮时插入工具提示的代码: @Directive({ selector: '[popover]'}) class Popover { private _component: ComponentRef<>; constructor(private _vcRef: ViewContainerRef, private _cfResolver:

我使用的是工具提示指令,因此当我单击一个
-时,我会动态地插入并显示工具提示

它确实工作得很好,我确实看到了工具提示:

这是我用来在单击按钮时插入工具提示的代码:

@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;
    }
  }
} 
@指令({selector:'[popover]})
类爆米花{
私有_组件:ComponentRef;
构造函数(private _vcRef:ViewContainerRef,private _cfResolver:ComponentFactoryResolver,private elementRef:elementRef){
}
@HostListener('单击')
切换(){
如果(!此._组件){
const componentFactory=this.\u cfResolver.resolveComponentFactory(PopoOverIndow);
this.\u component=this.\u vcRef.createComponent(componentFactory);
}否则{
这个._vcRef.clear()
此._component.destroy();
此._组件=空;
}
}
} 
但我不希望屏幕上出现多个工具提示。
换句话说,在我注入工具提示之前,我想删除所有现有的工具提示(如果有的话)

问题:

在插入新工具提示之前,如何“查找”所有现有工具提示并将其删除

我知道我可以在每个类中添加一个类,然后通过removeNode删除它们,但我想以一种有角度的方式来完成


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

一个明显正确的答案是使用一个服务,让您的弹出窗口注入此服务,并在其打开和关闭时注册,以了解是否有当前的弹出窗口打开

但让我们看看另一个不太明显的解决方案。。这可能会让人皱眉,但对于像这样的小事,似乎真的是最简单易读的方法。要在
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;
  }
} 
您的指令如下所示:

@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;
  }
}
@指令({selector:'[popover]})
类爆米花{
private get active(){
返回this.popoverService.isActive(this);
} 
私有组件:ComponentRef;
建造师(
私有vcRef:ViewContainerRef,
专用cfResolver:ComponentFactoryResolver,
private elementRef:elementRef,
专用popoverService:popoverService
) {}
@HostListener('文档:单击')
onDocClick(){
如果(此.active){
这个。关闭();
}
}
@HostListener('单击',['$event']))
切换(事件:MouseEvent){
如果(!this.active){
这个.open();
事件。stopImmediatePropagation();
}
}
开(){
const componentFactory=this.cfResolver.resolveComponentFactory(POPOOVINDOW);
this.component=this.vcf.createComponent(componentFactory);
this.popoOverService.setActive(this);
}
关闭(){
this.vcRef.clear()
this.component.destroy();
this.component=null;
}
}

关于“正确的方法”-您是指顶级(单例)注入服务,它包含对每个侦听“closeAll()事件的可见弹出窗口的引用吗?然后遍历数组并在每个指令?Sorta处调用
closeMe()
。但是您不需要关闭所有的,因为只有一个活动的。您应该让组件对服务说。。嗨,我现在是活跃的。。从服务中,关闭上一个(如果有),并将其设置为hiii活动oneService无法关闭任何内容。它通过一个主题发布(next())一个事件,该主题具有所选的ref(如您所说的活动的ref),并在每个指令的下标处检查ref是否为this,如果不是,则删除自身。对吗?我将使用服务添加“解决方案”。等等:)这里还有一个方法检查,还有这个问题:-@yurzui一如既往,谢谢。@yurzui你能看一下吗?
@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;
  }
}