最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is nativeElement undefined? - Stack Overflow

programmeradmin10浏览0评论

In my parent ponent, I have a btn and a settings menu directive. What I am trying to do is pass the elementref #navBtn as an input into 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;

I need this elementref so I can check to see if an event target includes/excludes this element in a HostListener on offclick.

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

But this.btn returns the btn html and not an elementRef it seems, because nativeElement on this.btn is always undefined, even in the ngAfterViewInit lifecycle hook.

In my parent ponent, I have a btn and a settings menu directive. What I am trying to do is pass the elementref #navBtn as an input into 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;

I need this elementref so I can check to see if an event target includes/excludes this element in a HostListener on offclick.

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

But this.btn returns the btn html and not an elementRef it seems, because nativeElement on this.btn is always undefined, even in the ngAfterViewInit lifecycle hook.

Share Improve this question asked Dec 20, 2017 at 14:50 YeysidesYeysides 1,2921 gold badge19 silver badges27 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

As mentioned in the Angular documentation about 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>

In most cases, Angular sets the reference variable's value to the element on which it was declared. In the previous example, phone refers to the phone number box. The phone button click handler passes the input value to the ponent's callPhone method.


In your code, if you pass navBtn as an input value to settings-menu:

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

btn will be set to the DOM element referred to by #navBtn. You could define the btn variable as an HTMLElement in the settings-menu ponent:

@Input("btn") btn: HTMLElement;

On the other hand, if you retrieve the element with @ViewChild("navBtn") in its own ponent, then you get an ElementRef, with a nativeElement property that points to the DOM element.

发布评论

评论列表(0)

  1. 暂无评论