【问题标题】:How to display a progress-spinner while fetching data via a Resolver in Angular 14?如何在通过 Angular 14 中的解析器获取数据时显示进度微调器?
【发布时间】:2023-02-02 22:27:05
【问题描述】:

我正在使用 Angular 14 和 PrimeNG 14。在我的模块中,我创建了默认路由,这取决于从解析器获取数据。我希望用户看到一个微调器,直到来自解析器的数据返回。我的路线是这样设置的......

const routes: Routes = [
  {
    path: '',
    component: MyComponent,
    resolve:{
      myData:MyResolver
    }
  } 
]

在 my-component.ts 文件中,我尝试像这样设置加载状态

  loading = true;

  constructor(private router: Router) {
    console.log("subscribing ...");
    this.router.events.subscribe(routerEvent => {
      this.checkRouterEvent((routerEvent as RouterEvent));
    });
  }

  checkRouterEvent(routerEvent: RouterEvent): void {
    if (routerEvent instanceof NavigationStart) {
      this.loading = true;
      console.log("starting.");
    }

    if (routerEvent instanceof NavigationEnd ||
      routerEvent instanceof NavigationCancel ||
      routerEvent instanceof NavigationError) {
      this.loading = false;
      console.log("done.");
    }
  }

在 my-component.html 文件中,我有

<ng-template [ngIf]="loading">
  <p-progressSpinner></p-progressSpinner>
</ng-template>
<ng-template [ngIf]="!loading">
...
</ng-template>

但是,我从来没有看到进度微调器。即使我关闭端点或断开与 Internet 的连接(我希望这会导致无限旋转),我的页面上也没有微调器。我该如何解决?

编辑:正在发生的事情的演示——https://stackblitz.com/edit/primeng-progressspinner-demo-t2taze?file=src/app/app.module.ts

【问题讨论】:

  • 但是,当您检查控制台输出时,console.log("starting.");console.log("done."); 是否按预期工作并且 to console.logs 至少间隔几毫秒?
  • 我只是将 &lt;p-progressSpinner&gt;&lt;/p-progressSpinner&gt; 放入您的 html(没有 NgIf)中,微调器是否正确显示?
  • @kellermat,如果我在那里没有 *ngIf 语句,微调器 apperas(最终)。 “最终”意味着解析器完成时(似乎组件仅在解析器完成后才初始化并在模块内呈现)。我已经包含一个演示链接作为对我的问题的编辑。
  • 我完全重写了我的答案并更新了我的 stackblitz-example(见下文)。我还包括了对已解析数据的实际获取(见下文)。

标签: angular spinner resolver angular14


【解决方案1】:

通过解析器获取数据时显示进度微调器

根据你的 stackblitz-example,我修改了我的Stackblitz Demo以及我的回答。关键事实:

  • 孩子-组件在路由完全完成之前不会加载 已解决,因此它无法触发加载微调器。
  • 因此父母-组件(而不是子组件)必须跟踪解析器的开始和完成。
  • 进度微调器的 HTML 代码也必须是 放置在父母-成分

应用模块:

我建议在应用程序模块中定义整个路由,只要我们没有延迟加载的功能模块(在 stackblitz 示例中,路由分布在两个模块中,因为我不想与 Dave 的解决方案偏离太多)。

const routes: Routes = [
  {
    path: '',
    component: ChildComponent,
    resolve: {
      myData: MyResolver,
    },
  },
];

父组件 TS:

export class AppComponent implements OnDestroy {
  unsubscribe = new Subject<void>();

  loading = true;

  constructor(private router: Router) {
    console.log('subscribing ...');
    this.router.events.pipe(takeUntil(this.unsubscribe))
      .subscribe((routerEvent) => {
        this.checkRouterEvent(routerEvent as RouterEvent);
      });
  }

  checkRouterEvent(routerEvent: RouterEvent): void {
    if (routerEvent instanceof NavigationStart) {
      this.loading = true;
      console.log('starting.');
    }

    if (routerEvent instanceof NavigationEnd ||
        routerEvent instanceof NavigationCancel ||
        routerEvent instanceof NavigationError) {
        this.loading = false;
        console.log('done.');
    }
  }

  ngOnDestroy(): void {
    this.unsubscribe.next();
  }
}

父组件 HTML:

router-outlet在解析完数据后才会加载。

<ng-template [ngIf]="loading">
  <p-progressSpinner></p-progressSpinner>
</ng-template>

<router-outlet></router-outlet>

子组件 TS:

这里可以同步访问来自解析器的数据,即数据必须在子组件加载时已经解析:

resolvedData: any;

constructor(private route: ActivatedRoute) {

  // Access the resolved data:
  this.resolvedData = this.route.snapshot.data.myData;

  // Subscribing to the Router would be worthless at this point,
  // since the data is already resolved.
}

【讨论】:

  • 感谢这个演示。所以这个问题似乎发生在主应用程序的一个模块中。使用您的演示,我创建了自己的一个 -- stackblitz.com/edit/… 。您可以看到 5 秒内没有微调器出现(您设置的延迟),然后突然加载了所有内容。
  • 我完全重写了我的答案以及我的 stackblitz-example。
  • 感谢您的努力。不幸的是,将解析器和其他组件逻辑移动到应用程序模块不是一个选项(我正在使用模块联合导出我的模块)。我需要将所有这些包含在我的自定义模块本身中。
  • 也许你应该在你的问题中提到这个限制,它会节省我很多工作......我想你所要求的基本上是不可能的。即使您使用skipLocationChange,在解析器完成之前也只会呈现子组件的打字稿代码,但 HTML 仍然不会呈现,直到进度微调器显示为时已晚。
  • 因此,尽管 Angular 现在的版本是 14,但不能在自定义模块中使用解析器吗?我没有在他们的文档中阅读有关此类限制的任何内容,但也许我误解了解析器的用途。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2020-01-23
  • 2013-06-05
  • 2019-07-19
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多