Angular 2/4如何确定嵌套属性指令中子指令传播的事件的起源?

时间:2017-08-31 19:13:10

标签: html angular dom attributes angular-directive

我在处理悬停事件时遇到问题,该事件是从具有相同指令的嵌套元素的子代传播的。我对Angular很新,所以如果我遗漏了一些明显的东西,请保持温柔并忍受我。

我想要完成的任务:

我有一个自定义属性指令,我正在编写这个指令来创建一个伪维恩图ui模块,其中一个圆圈会在悬停时展开。我的想法是我试图使用一个自定义指令来实现这一点,行为根据dom中元素的位置而变化,如果带有指令标记的元素的父元素不是带有指令标记的另一个元素,那么它被视为“根圆”,否则如果带有标记的元素具有带有指令标记的父元素,则它将被视为“子圆”,如下所示。

      <div vennCircle diameter="20vh" percentOverlap="35" parentAngle="300" id="smc">
        Parent
        <div vennCircle diameter="30vh" percentOverlap="35" parentAngle="0" id="smc1">
          child 1
        </div>
        <div vennCircle diameter="30vh" percentOverlap="35" parentAngle="90" id="smc2">
          child 2
        </div>
      </div>

我按照Angular Docs for finding a parent component through injecting创建了如下所示的指令,并且能够使用它来成功区分父指令与子指令元素。

export abstract class Parent { name: string; }

@Directive({
  selector: '[vennCircle]',
  providers: [{ provide: Parent, useExisting: forwardRef(() => VennDiagramDirective) }]
})
export class VennDiagramDirective implements AfterViewInit, Parent {
  name: string

  constructor(private el: ElementRef, @SkipSelf() @Optional() public parent: Parent) {
    console.log(el);
    console.log(parent);
  }

  @HostListener('mouseenter', ['$event']) onMouseEnter(event: any) {
    this.el.nativeElement.style.backgroundColor = 'rgba(0,0,255,1)';
  }
}

以下是用于创建自定义属性指令的Angular文档(我可以发布的链接数量有限)我试图捕获悬停事件以触发上面代码中的其他行为,它只是更改背景元素的颜色悬停在上面。

我的问题:

我遇到的问题是,如果我将鼠标悬停在父圆圈上,一切都按预期工作,背景颜色会发生变化,但是如果我将鼠标悬停在两个子圆圈中的任何一个上,它们也会改变颜色,但是自事件传播以来,父圈也是如此,下面的图像展示了它的样子:

link to picture

现在我可能是Angular的新手,但这种行为本身并不让我感到惊讶,我的理解是事件传播或冒泡,我的印象是这应该首先发生在最低层并向上移动在层次结构中。如果我的理解是正确的,那么应该遵循当孩子盘旋时子圈指令首先应该接收到悬停事件,然后应该在树中向上传播到父圈。如果接下来,那么我应该能够在第一次收到事件时停止传播事件,导致只有子圈改变颜色,但事实并非如此。

当我使用时间戳打印到控制台时,它显示父圈(“#smc”)正在接收子事件(“#smc1”)之前的事件,如下所示:

ElementRef {nativeElement: div#smc}
1504205896178
ElementRef {nativeElement: div#smc1}
1504205896206

我的问题

  • 如果可能,我如何阻止父元素指令接收其子元素的悬停事件?
  • 如果上述情况不可能,我如何确定悬停事件的来源,以便我可以过滤出父元素指令中子元素的事件?

备注

  • 我目前已经准备好用单一指令实现这一目标,即使它很棘手,我的想法是我希望能够在别处使用这个ui模块或者与其他人共享,只需要一个module.ts中的单个声明/导入。我已经知道我可以为每种类型的圆创建X个不同的组件/指令,但是我不希望这样,这使得我认为使用模块过于复杂。
  • 我不希望使用它的开发人员必须在html中手动设置事件,属性指令启用了这个,所以我希望能够使用它。

提前感谢您的帮助,如果您需要更多信息,请发表评论,或者如果我做错了,请记住我是新手并且学习!

0 个答案:

没有答案