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;
}
}