Где DOM-манипуляция принадлежит Angular 2?

В 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-манипулирование компонентом в директиве?

Все это просто размытие в данный момент, поэтому я не уверен, что все правильно, и я уверен, что я не единственный.

Каковы правила манипуляции DOM в Angular2?

Ответы

Ответ 1

Прямой манипуляции с DOM следует избегать полностью в Angular2.

Используйте вместо привязки как:

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

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

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

Ответ 2

Основываясь на рекомендуемом решении разработчиков: 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
  }
}

Внимание. Имя дочернего элемента представления должно начинаться с имени my и в шаблоне, который вам нужен. #.