DOM 操作在 Angular 2 中属于哪里?

Posted

技术标签:

【中文标题】DOM 操作在 Angular 2 中属于哪里?【英文标题】:Where does DOM manipulation belong in Angular 2? 【发布时间】:2016-09-19 11:24:22 【问题描述】:

在 Angular 1 中,所有 DOM 操作都应该在指令中完成以确保适当的可测试性,但是 Angular 2 呢?这有什么变化?

我一直在寻找好的文章或任何关于在哪里放置 DOM 操作以及在操作时如何思考的信息,但每次都找不到。

以这个组件为例(这确实是一个指令,但我们假设它不是):

export class MyComponent 

  constructor(private _elementRef: ElementRef) 

    this.setHeight();

    window.addEventListener('resize', (e) => 
      this.setHeight();
    );
  

  setHeight() 
    this._elementRef.nativeElement.style.height = this.getHeight() + 'px';
  

  getHeight() 
    return window.innerHeight;
  

例如,事件绑定是否属于构造函数,或者应该将其放在ngAfterViewInit 函数中还是其他地方?您是否应该尝试将组件的 DOM 操作分解为指令?

目前这一切都只是一个模糊,所以我不确定我是否正确地处理它,我确定我不是唯一一个。

Angular2 中 DOM 操作的规则是什么?

【问题讨论】:

【参考方案1】:

基于开发者推荐的解决方案:http://angularjs.blogspot.de/2016/04/5-rookie-mistakes-to-avoid-with-angular.html

@Component(
  selector: 'my-comp',
  template: `
    <div #myContainer>
    </div>
  `
)
export class MyComp implements AfterViewInit 
  @ViewChild('myContainer') container: ElementRef;

  constructor() 

  ngAfterViewInit() 
    var container = this.container.nativeElement;
    console.log(container.width); // or whatever
  

注意:视图子名称必须以myName 开头,并且在您需要的模板中#。

【讨论】:

不要忘记添加适当的导入: import AfterViewInit, ViewChild from '@angular/core';代码摘自:angular.io/docs/ts/latest/cookbook/… 你还需要包含 import ElementRef from '@angular/core'; 您是说前缀my 必须出现在名称中吗?或者你的意思是我们在@ViewChild('whatever')中引用的名称必须与模板标记中的#whatever对应? @KonradViltersten 它可能不再与您相关,但可能仍与其他人相关; “my”前缀不必出现在名称中,只要相同即可,但强烈建议使用个人/自定义前缀,以免干扰其他模块。【参考方案2】:

在 Angular2 中应该完全避免直接的 DOM 操作。

改用如下绑定:

export class MyComponent 
  constructor() 
    this.setHeight();
  

  @HostBinding('style.height.px')
  height:number;

  @HostListener('window:resize', ['$event'])
  setHeight() 
    this.height = window.innerHeight;
  

【讨论】:

你能详细说明吗? @HostListener(...) 注册一个事件监听器,@HostBinding(...)height 样式值更新为分配给number 的值。事件处理程序不正确。我更新了我的答案(对不起,我写的时候只是在电话里)。 直接 DOM 操作与服务器端渲染和利用 Angulars WebWorkers 支持不兼容。 嗯好吧,我有点明白,但我不太明白这个@HostBinding('style.height.px') height:number;height:number 部分是做什么的? 这似乎表明监听器会监听宿主元素来调整大小而不是窗口?

以上是关于DOM 操作在 Angular 2 中属于哪里?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 2 + Google Maps Places Autocomplete,在输入后追加 [Dom 操作]

angular中如何监控dom渲染完毕

Angular使用总结 --- 如何正确的操作DOM

在 Angular2 中操作 DOM 的更好方法

Angular Directive DOM 操作行为

Angular VS jQuery