【问题标题】:My template reference variable .nativeElement is undefined我的模板引用变量 .nativeElement 未定义
【发布时间】:2018-07-05 22:26:22
【问题描述】:

this.child02.nativeElement 未定义,我不知道为什么。我究竟做错了什么?谢谢你。这是我的current stackblitz.

app.component.ts:

import { Component,ElementRef,ViewChild } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {

switchDirection = true;
head: ElementRef;

@ViewChild('child02') child02: ElementRef;

  onScroll(event: Event) {
    console.log("viewBoundaryL:" + (event.target as HTMLElement).scrollLeft);
    if((event.target as HTMLElement).scrollLeft >= 50 && this.switchDirection === true){
  console.log("nativeElement:" + this.child02.nativeElement)
  console.log(this.child02)
  console.log('snap')
this.child02.nativeElement.scrollIntoView({ behavior: 'smooth' });
  this.switchDirection = false;
    }
  }
}

app.component.html:

Keep an eye on the console while scrolling...
<div class="container"  (scroll)="onScroll($event)" >

<child1></child1>
<child2 #child02></child2>
<child3></child3>

</div>

上下文: 我正在尝试制作一个 snap-to-component-directive,类似于 this functionality (open in firefox). 这是我的 current stackblitz. 我的问题是你将如何构建这个?尽量不使用单例。

有很多方法可以做到这一点,但这里有一种方法:当用户从一个组件水平滚动到另一个组件时,它进入到视图中超过子组件边界 50 像素或更多像素时,组件将 scrollIntoView()。需要一个 switchDirection 变量,以便一旦快照发生,它就不会在相同的定位逻辑上运行。我想再次将其放入指令中。

用于在 child 1 和 child2 之间捕捉的上述逻辑的伪代码(有关上下文,请参见 stackblitz 控制台):

//snap from child1 to child2
    If (viewBoundary >= child1L + 50px && switchDirection === true){
child2.scrollIntoView();
switchDirection = false;
debounceTime(250);
}
//snap from child2 to child1
else if(viewBoundary <= child1R - 50px && switchDirection === false){
child1.scrollIntoView();
switchDirection = true;
debounceTime(250);
}

感谢您的见解!

【问题讨论】:

    标签: angular typescript angular-template


    【解决方案1】:

    将@ViewChild 声明更新为:

    @ViewChild('child02',{read: ElementRef}) child02: ElementRef;
    

    保持其他一切不变。

    Example

    【讨论】:

      【解决方案2】:

      您需要使用el 访问该元素,如下所示。这是因为您在自定义组件上定义了#child02,它不是本机元素,因此您需要通过el 访问它。

      this.child02.el.nativeElement.scrollIntoView({ behavior: 'smooth' });
      

      我已验证,没有更多控制台错误。

      https://stackblitz.com/edit/angular-horizontalscrollsetup-logging2-e7b9jy?file=app/app.component.ts


      但是,请使用属性# 作为最后的手段,因为它会导致您的应用程序紧密耦合。

      您可以参考以下链接了解更多信息。

      https://angular.io/api/core/ElementRef

      【讨论】:

      • 谢谢!我在 div 对象上看到了它并把它放进去,但是当我看到 stackblitz 的红色波浪形错误时,我就回避了……奇怪它是如何在 stackblitz 中作为我的错误出现的,但在运行时工作正常。这也发生在你身上吗?
      • 那是因为您已经将child02 定义为ElementRef 类型,但是内部的el 属性是ElementRef 类型。如果你在div 上使用它,那么它会按预期工作。
      • 链接angular.io/api/core/ElementRef为您解答。如果您无法以任何其他方式访问 DOM,那么只有您应该使用 #
      • 这完全是意料之中的,但在这里您在自定义组件上提供此标签。在这些情况下,标签必须直接位于某些原生 HTML 标签上,例如 divul 等。
      • 好的,我知道他们现在在哪里提供替代解决方案。 “改用 Angular 提供的模板和数据绑定。或者,您可以查看 Renderer2,它提供的 API 即使在不支持直接访问本机元素时也可以安全使用。”谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-05
      相关资源
      最近更新 更多