Angular Universal - 不应使用超时 [英] Angular Universal - timeout should not be used

查看:27
本文介绍了Angular Universal - 不应使用超时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我一直在尝试将我的应用程序转换为 angular Universal,并且在大多数情况下它都很好.但我之前读过一些陷阱":https://github.com/onespeed-articles/angular-universal-gotchas

so I have been trying to convert my application into angular universal, and for the most part it has been fine. But I read some "gotchas" earlier: https://github.com/onespeed-articles/angular-universal-gotchas

这表明我不应该使用令人讨厌的 timeout,因为在 angularjs 中,您使用它在渲染视图后触发事物,因此您可以确定元素的尺寸是否正确等

It suggests that I should not be using timeout which is annoying, because in angularjs you used it to make things fire after a view was rendered so you could be sure that dimensions of elements were correct, etc.

我还读到它仍然存在于 angular 6 所以我有这个指令:

I have also read that it still persists in angular 6 so I have this directive:

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 秒.如果这是不好的做法,我应该改用什么?

When the browser resizes, it waits for .5 of a second before it tries to resize the button group. If this is bad practice, what should I use instead?

推荐答案

当浏览器调整大小时,它会在尝试调整按钮组大小之前等待 0.5 秒.如果这是不好的做法,我应该改用什么?

When the browser resizes, it waits for .5 of a second before it tries to resize the button group. If this is bad practice, what should I use instead?

您正在延迟每个调整大小事件.通常,您希望每 500 毫秒去抖动和处理一个事件.这可以使用 observable 来完成,但请确保在组件销毁时取消订阅.

You are delaying every resize event. Generally, you want to debounce and handle only one event every 500ms. This can be done using an observable, but make sure to unsubscribe when the component is destroyed.

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

还有 @HostListener() 在服务器端渲染期间从不触发事件.服务器上没有 DOM 来触发窗口大小调整事件.

Also @HostListener() never fires events during server-side rendering. There is no DOM on the server to trigger window resize events.

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

您在此处使用的 setTimeout 全局函数在 NodeJS 中具有不同的函数签名.当您在 Angular Universe 中运行应用程序时,它会在 NodeJS 内部运行以生成 HTML,然后再进入 Web 浏览器.setTimeout 在 Web 浏览器上返回一个数字,但在 NodeJS 中返回一个资源句柄.

The setTimeout global function that you are using here has a different function signature in NodeJS. When you run the application in Angular Universe it runs inside NodeJS to generate the HTML before it goes to the web browser. setTimeout returns a number on web browsers but returns a resource handle in NodeJS.

如果您打算在 Angular Universal 中运行您的应用程序,那么这意味着您正在编写与 Web 浏览器分离的源代码.这意味着没有对 DOM 的直接操作,没有全局变量,也没有全局 window 变量.

If you're going to run your application in Angular Universal then it means you're writing source code that is decoupled from the web browser. That means no direct manipulation of the DOM, no global variables and no global window variable.

这篇关于Angular Universal - 不应使用超时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆