代码之家  ›  专栏  ›  技术社区  ›  r3plica

角度通用-不应使用超时

  •  0
  • r3plica  · 技术社区  · 7 年前

    因此,我一直在尝试将我的应用程序转换为角度通用程序,在大多数情况下,它都很好。 https://github.com/onespeed-articles/angular-universal-gotchas

    timeout 这很烦人,因为 安格拉斯 您使用它在渲染视图后触发事件,以便确保元素的尺寸正确,等等。

    角度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';
        }
      }
    }
    

    如果这是不好的做法,我应该用什么来代替?

    2 回复  |  直到 7 年前
        1
  •  4
  •   Sandeep Gupta    7 年前

    您希望该代码在浏览器中运行,而不是在服务器中运行。您提供的链接为您提供了解决方案:

     if (isPlatformBrowser(this.platformId)) {
          //your setTimeout here
      }
    
        2
  •  3
  •   Reactgular    7 年前

    当浏览器调整大小时,它会等待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中运行应用程序时,它会在NodeJ中运行,以在进入web浏览器之前生成HTML。setTimeout在web浏览器上返回一个数字,但在NodeJS中返回一个资源句柄。

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

    推荐文章