当前位置: 首页 > 面试题库 >

在Angular 2中的路线之间导航时显示加载屏幕

郁权
2023-03-14
问题内容

在Angular 2中更改路线时如何显示加载屏幕?


问题答案:

当前的AngularRouter提供导航事件。您可以订阅这些内容并相应地更改UI。请记住要计入其他事件,例如,NavigationCancelNavigationError在路由器转换失败时停止旋转器。

app.component.ts- 您的根组件

...
import {
  Router,
  // import as RouterEvent to avoid confusion with the DOM Event
  Event as RouterEvent,
  NavigationStart,
  NavigationEnd,
  NavigationCancel,
  NavigationError
} from '@angular/router'

@Component({})
export class AppComponent {

  // Sets initial value to true to show loading spinner on first load
  loading = true

  constructor(private router: Router) {
    this.router.events.subscribe((e : RouterEvent) => {
       this.navigationInterceptor(e);
     })
  }

  // Shows and hides the loading spinner during RouterEvent changes
  navigationInterceptor(event: RouterEvent): void {
    if (event instanceof NavigationStart) {
      this.loading = true
    }
    if (event instanceof NavigationEnd) {
      this.loading = false
    }

    // Set loading state to false in both of the below events to hide the spinner in case a request fails
    if (event instanceof NavigationCancel) {
      this.loading = false
    }
    if (event instanceof NavigationError) {
      this.loading = false
    }
  }
}

app.component.html- 您的根视图

<div class="loading-overlay" *ngIf="loading">
    <!-- show something fancy here, here with Angular 2 Material's loading bar or circle -->
    <md-progress-bar mode="indeterminate"></md-progress-bar>
</div>

提高性能的答案
:如果您关心性能,有更好的方法,则实现起来会有些繁琐,但是提高性能值得进行额外的工作。代替使用*ngIf有条件地显示微调器,我们可以利用Angular的功能NgZoneRenderer打开/关闭微调器,这将在我们更改微调器的状态时绕过Angular的更改检测。与使用*ngIfasync管道相比,我发现这可以使动画更流畅。

这与我以前的回答类似,但有一些调整:

app.component.ts- 您的根组件

...
import {
  Router,
  // import as RouterEvent to avoid confusion with the DOM Event
  Event as RouterEvent,
  NavigationStart,
  NavigationEnd,
  NavigationCancel,
  NavigationError
} from '@angular/router'
import {NgZone, Renderer, ElementRef, ViewChild} from '@angular/core'


@Component({})
export class AppComponent {

  // Instead of holding a boolean value for whether the spinner
  // should show or not, we store a reference to the spinner element,
  // see template snippet below this script
  @ViewChild('spinnerElement')
  spinnerElement: ElementRef

  constructor(private router: Router,
              private ngZone: NgZone,
              private renderer: Renderer) {
    router.events.subscribe(this._navigationInterceptor)
  }

  // Shows and hides the loading spinner during RouterEvent changes
  private _navigationInterceptor(event: RouterEvent): void {
    if (event instanceof NavigationStart) {
      // We wanna run this function outside of Angular's zone to
      // bypass change detection
      this.ngZone.runOutsideAngular(() => {
        // For simplicity we are going to turn opacity on / off
        // you could add/remove a class for more advanced styling
        // and enter/leave animation of the spinner
        this.renderer.setElementStyle(
          this.spinnerElement.nativeElement,
          'opacity',
          '1'
        )
      })
    }
    if (event instanceof NavigationEnd) {
      this._hideSpinner()
    }
    // Set loading state to false in both of the below events to
    // hide the spinner in case a request fails
    if (event instanceof NavigationCancel) {
      this._hideSpinner()
    }
    if (event instanceof NavigationError) {
      this._hideSpinner()
    }
  }

  private _hideSpinner(): void {
    // We wanna run this function outside of Angular's zone to
    // bypass change detection,
    this.ngZone.runOutsideAngular(() => {
      // For simplicity we are going to turn opacity on / off
      // you could add/remove a class for more advanced styling
      // and enter/leave animation of the spinner
      this.renderer.setElementStyle(
        this.spinnerElement.nativeElement,
        'opacity',
        '0'
      )
    })
  }
}

app.component.html- 您的根视图

<div class="loading-overlay" #spinnerElement style="opacity: 0;">
    <!-- md-spinner is short for <md-progress-circle mode="indeterminate"></md-progress-circle> -->
    <md-spinner></md-spinner>
</div>


 类似资料:
  • 在游戏开始之前,我想显示一条消息,说“游戏开始!”。消息从左到右穿过屏幕,只有当消息已经消失时,游戏才开始。 我遇到的问题是,lifeTable的实例化需要时间,GameScreen在实例化完成之前就开始运行。我解释说: 当我禁用lifeTable时,一切都运行得很顺利,“游戏开始了!”消息从左到右穿过屏幕,游戏开始。 当我启用lifeTable时,当我按下MainMenueScreen中的“Ne

  • 这是来自Google Adsense应用程序页面的示例。显示在主页之前的加载屏幕显示在之后。 我不知道如何使用React做同样的事情,因为如果我让React组件渲染加载屏幕,它不会在页面加载时显示,因为它必须等待之前渲染的DOM。 更新: 我以我的方法为例,将屏幕加载程序放入中,并在Reactlifecycle方法中删除它。 示例和反应加载屏幕。

  • ap.showNavigationBarLoading() 显示导航栏加载图标。 代码示例 <script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js"></script> <button class="btn btn-default">showNavigationB

  • 在我的反应原生应用程序中,我有一个切换导航器来在认证堆栈和应用堆栈之间导航: 它可以工作,但是当我从AuthStack转到AppStack时,它会闪烁,屏幕会向上移动。我如何防止这种行为增加平稳过渡。

  • 问题内容: 更新后,我已将角度包版本从2.4.10更新到4.0.0,导航时出现以下错误。 而且我更改了webpack.common.js配置。见下面的代码 问题答案: 我已经解决了这个问题。我添加了一个新包:。 我导入了模块:

  • 我想在API调用时在flutter中显示全屏加载视图。但是当我在脚手架体中添加加载小部件时,它出现在appbar和底部导航器之后。 我花了很多时间在全屏显示加载视图。另外,我希望在API调用时防止后退操作。