如何在Angular 7.1中实现全局加载器

Twi*_*her 15 angular angular-cdk angular7

我有一个全局加载器,实现如下:

CoreModule:

router.events.pipe(
  filter(x => x instanceof NavigationStart)
).subscribe(() => loaderService.show());

router.events.pipe(
  filter(x => x instanceof NavigationEnd || x instanceof NavigationCancel || x instanceof NavigationError)
).subscribe(() => loaderService.hide());
Run Code Online (Sandbox Code Playgroud)

LoaderService:

@Injectable({
    providedIn: 'root'
})
export class LoaderService {

    overlayRef: OverlayRef;
    componentFactory: ComponentFactory<LoaderComponent>;
    componentPortal: ComponentPortal<LoaderComponent>;
    componentRef: ComponentRef<LoaderComponent>;

    constructor(
        private overlay: Overlay,
        private componentFactoryResolver: ComponentFactoryResolver
    ) {
        this.overlayRef = this.overlay.create(
            {
                hasBackdrop: true,
                positionStrategy: this.overlay.position().global().centerHorizontally().centerVertically()
            }
        );

        this.componentFactory = this.componentFactoryResolver.resolveComponentFactory(LoaderComponent);

        this.componentPortal = new ComponentPortal(this.componentFactory.componentType);
    }

    show(message?: string) {
        this.componentRef = this.overlayRef.attach<LoaderComponent>(this.componentPortal);
        this.componentRef.instance.message = message;
    }

    hide() {
        this.overlayRef.detach();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用Angular 7.0.2时,行为(我想要的)是:

  • 在解析附加到路由的数据时以及加载延迟模块时显示加载程序
  • 在没有任何解析器的情况下导航到路线时不要显示装载器

我已更新到Angular 7.2,现在的行为是:

  • 在解析附加到路由的数据时以及加载延迟模块时显示加载程序
  • LoaderComponent没有任何解析器的情况下导航到路线时显示叠加

我已经添加了一些关于NavigationStartNavigationEnd事件的日志,我发现它NavigationEnd是在紧接着之后触发的NavigationStart(这是正常的),而Overlay在0.5s后消失了.

我已经读过了,CHANGELOG.md但我发现没有什么可以解释这个问题.欢迎任何想法.

编辑:

经过进一步的研究,我通过这样设置恢复了以前的行为package.json:

"@angular/cdk": "~7.0.0",
"@angular/material": "~7.0.0",
Run Code Online (Sandbox Code Playgroud)

而不是这个:

"@angular/cdk": "~7.2.0",
"@angular/material": "~7.2.0",
Run Code Online (Sandbox Code Playgroud)

我已经确定了在7.1.0版本中发布的错误提交,并且我在相关的GitHub问题上发布了我的问题.它修复了淡出动画Overlay.

什么是符合v7.1 +标准的方式来获得所需的行为?据我所知,最好的办法是:只在必要时显示加载程序,但NavigationStart不保存所需的信息.我想避免最终出现一些去抖行为.

Twi*_*her 3

这是我在意识到 a 在用户体验方面是一个很好的解决方案之后得到的结果,delay因为它允许加载程序仅在加载时间值得显示加载程序时才显示。

我不喜欢这个解决方案,因为我更喜欢将状态封装到Observable运算符中而不是共享变量中,但我无法实现它。

counter = 0;

router.events.pipe(
  filter(x => x instanceof NavigationStart),
  delay(200),
).subscribe(() => {
  /*
  If this condition is true, then the event corresponding to the end of this NavigationStart
  has not passed yet so we show the loader
  */
  if (this.counter === 0) {
    loaderService.show();
  }
  this.counter++;
});

router.events.pipe(
  filter(x => x instanceof NavigationEnd || x instanceof NavigationCancel || x instanceof NavigationError)
).subscribe(() => {
  this.counter--;
  loaderService.hide();
});
Run Code Online (Sandbox Code Playgroud)