【问题标题】:Where does DOM manipulation belong in Angular 2?DOM 操作在 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 操作的规则是什么?

【问题讨论】:

    标签: angular dom-manipulation


    【解决方案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 部分是做什么的?
    • 这似乎表明监听器会监听宿主元素来调整大小而不是窗口?
    猜你喜欢
    • 2017-04-07
    • 2017-05-16
    • 2010-10-08
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2018-03-10
    相关资源
    最近更新 更多