“正确”的方式来访问Angular 2模板之外的DOM元素?

时间:2018-07-19 17:45:44

标签: javascript angular dom

我有一个正确的答案:“您不使用服务或其他解决方案”,但是,出于这个问题,我不得不说。

我渲染的页面看起来像这样:

<div class="somePageHeader">Welcome to my site!</div>
<div my-angular-component>Hi, I'm an angular component!</div>
<div class="somePageFooter">Welcome to my site!</div>

在这种特殊情况下,根据my-angular-component内部发生的情况,我可能需要滚动页面。要知道在何处滚动,我需要考虑组件外部一些固定位置的元素(在此示例中,为网站的页眉和页脚)。因为此组件是在多个项目中共享的,所以我必须从组件内部检索这些元素的属性(特别是它们的高度)。

(免责声明:我知道这可能是一种不好的做法,并且应该在比我的组件更高的级别上进行,但是为了争论起见,让我们说我只需要使此工作生效而且我只能访问组件中的代码。

我的问题:角度自身内部是否存在一种“正确”的方式来访问当前角度组件模板之外的DOM元素的属性?

我们可以使用jQuery $('.somePageHeader'),但是-使用起来很简单-我知道在Angular中依靠jQuery是一个坏习惯。

我可以使用普通的JS getElementByClassName()document.querySelector(),(我认为?)就可以了。

但是,有没有更好,更以角度为中心的方法呢?我知道ViewChild,但是据我了解,那是为了访问模板内 而不是模板外的DOM元素。

1 个答案:

答案 0 :(得分:1)

考虑使用@ViewChild查询。

您可以使用它们从模板中获取本机HTML元素(通过其类选择器,id或通过#templateVariable引用),还可以使用其类名从整个组件中获取:

<my-component></my-component>

并在控制器中:

@ViewChild(MyComponentClass) variable: MyComponentClass

,甚至更进一步,如果指令使用exportAs注释(例如formGroup导出为ngForm),则可以将其分配给模板变量:

<input [formGroup]="groupName" #controlRef="ngForm">

并通过@ViewChild在您的组件中引用它:

@ViewChild('controlRef') cpomponentVariable;

查询其父组件之后,一切由您决定。但是请注意,将其存储在类似服务的位置以供以后访问。在关闭该父组件之后,将调用onDestory,并且您基本上将访问垃圾。

我认为这可能与某些设计问题有关,因为您通常不需要传递整个组件/模板变量,而只需传递它们的状态。

考虑使用一些基于面向服务的主题的事件总线系统来侦听状态更改,并在您可以访问您感兴趣的组件时通知它们。