Angular Universal - время ожидания не должно использоваться - PullRequest
0 голосов
/ 15 декабря 2018

поэтому я пытался преобразовать свое приложение в угловое универсальное, и по большей части это было хорошо.Но я читал некоторые "ошибки" ранее: https://github.com/onespeed-articles/angular-universal-gotchas

Это говорит о том, что я не должен использовать timeout, что раздражает, потому что в angularjs вы использовали его, чтобы заставить вещи срабатывать послепредставление было отображено, чтобы вы могли быть уверены, что размеры элементов были правильными и т. д.

Я также читал, что оно все еще сохраняется в угловом 6 , поэтому у меня есть эта директива:

import { Directive, ElementRef, AfterViewInit, Input, HostListener } from '@angular/core';

@Directive({
  selector: '[pyb-button-group]'
})
export class ButtonGroupDirective implements AfterViewInit {
  @Input() className: string;

  @HostListener('window:resize', ['$event'])
  onResize() {
    let resize = this.resize;
    let element = this.element;
    let className = this.className;

    setTimeout(function () {
      resize(element, className);
    }, 500);
  }

  constructor(private element: ElementRef) {
  }

  ngAfterViewInit() {
    this.resize(this.element, this.className);
  }

  resize(nativeElement, className) {
    let elements = nativeElement.nativeElement.getElementsByClassName(className || 'btn-choice');
    let headerHeight = 0;

    for (var i = 0; i < elements.length; i++) {
      let element = elements[i];
      let header = element.getElementsByClassName('header');

      if (!header.length) return;

      header = header[0];
      header.style.height = 'auto'; // Reset when resizing the window

      let height = header.offsetHeight;
      if (height > headerHeight) headerHeight = height;
    }

    for (var i = 0; i < elements.length; i++) {
      let element = elements[i];
      let header = element.getElementsByClassName('header');

      if (!header.length) return;

      header = header[0];
      header.style.height = headerHeight + 'px';
    }
  }
}

Когда размер браузера изменяется, он ждет 0,5 секунды, прежде чем пытается изменить размер группы кнопок.Если это плохая практика, что я должен использовать вместо этого?

Ответы [ 2 ]

0 голосов
/ 15 декабря 2018

Когда браузер изменяет размеры, он ждет 0,5 секунды, прежде чем попытается изменить размер группы кнопок.Если это плохая практика, что я должен использовать вместо этого?

Вы задерживаете каждое событие изменения размера.Как правило, вы хотите отменить и обрабатывать только одно событие каждые 500 мс.Это можно сделать с помощью наблюдаемого, но обязательно отмените подписку, когда компонент уничтожен.

observableFromEvent(window, 'resize')
  .pipe(debounceTime(500))
  .subscribe(() => this.resize(this.element, this.className))

Также @HostListener() никогда не запускает события во время рендеринга на стороне сервера.На сервере нет DOM для запуска событий изменения размера окна.

  setTimeout(function () {
      resize(element, className);
  }, 500);

Используемая здесь глобальная функция setTimeout имеет другую сигнатуру функции в NodeJS.Когда вы запускаете приложение в Angular Universe, оно запускается внутри NodeJS, чтобы сгенерировать HTML, прежде чем оно перейдет в веб-браузер.setTimeout возвращает число в веб-браузерах, но возвращает дескриптор ресурса в NodeJS.

Если вы собираетесь запускать свое приложение в Angular Universal, то это означает, что вы пишете исходный код, который отделен от веб-браузера.Это означает, что нет прямых манипуляций с DOM, нет глобальных переменных и глобальных оконных переменных.

0 голосов
/ 15 декабря 2018

Вы хотите, чтобы этот код запускался в браузере, а не на сервере.Ссылка, которую вы предоставили, дает вам решение:

 if (isPlatformBrowser(this.platformId)) {
      //your setTimeout here
  }
...