为什么nativeElement未定义?

时间:2017-12-20 14:50:10

标签: javascript angular typescript

在我的父组件中,我有一个btn和一个设置菜单指令。我想要做的是将elementref #navBtn作为输入传递到settings-menu。

    <div #navBtn (click)="toggleNav()" class="header__button header__button--left" id="header_button--left">
      <img class="align-absolute" src="assets/imgs/icon_sandwich.svg">
    </div>
    <settings-menu [btn]="navBtn" [navOpened]="navOpened" (navClosed)="navOpened.next(false)"></settings-menu>
...
@ViewChild('navBtn') navBtn: ElementRef;

我需要这个elementref所以我可以在offclick上检查事件目标是否包含/排除HostListener中的这个元素。

  private _btn: ElementRef;
  @Input('navOpened') navOpened: BehaviorSubject<boolean>;
  @Input('btn')
  set btn(val: ElementRef) {
    this._btn = val;
  }

  get btn() {
    return this._btn;
  }

  @HostListener('document:click', ['$event']) offClick(e: Event) {
    e.stopPropagation();
    console.log('el', this.el.nativeElement, 'btn', this.btn.nativeElement, 'target', e.target);
    if (!this.el.nativeElement.contains(e.target) || this.btn.nativeElement.contains(e.target)) this.closeNav();
  }

但是this.btn返回btn html而不是elementRef,因为this.btn上的nativeElement总是未定义,即使在ngAfterViewInit生命周期钩子中也是如此。

1 个答案:

答案 0 :(得分:5)

正如Angular文档中提到的template reference variables

<input #phone placeholder="phone number">

<!-- phone refers to the input element; pass its `value` to an event handler -->
<button (click)="callPhone(phone.value)">Call</button>
  

在大多数情况下,Angular将引用变量的值设置为   声明它的元素。在前面的例子中,电话   是指电话号码框。电话按钮单击处理程序   将输入值传递给组件的callPhone方法。

在您的代码中,如果您将navBtn作为输入值传递给settings-menu

<settings-menu [btn]="navBtn" ...>

btn将设置为#navBtn引用的DOM元素。您可以将btn变量定义为settings-menu组件中的HTMLElement:

@Input("btn") btn: HTMLElement;

另一方面,如果您在自己的组件中检索带有@ViewChild("navBtn")的元素,那么您将得到一个ElementRef,其nativeElement属性指向DOM元素。< / p>