【问题标题】:Angular | How to initially load data before the app is resolved?角 |如何在应用程序解析之前初始加载数据?
【发布时间】:2019-08-26 16:14:56
【问题描述】:

我正在使用 Angular 编写一个 Web 应用程序。

每次用户导航到该站点时,该应用都必须在准备好应用之前执行几次服务器调用。

我试图定义一个必须在 Routes 中解析的函数:

{path: '', resolve: {data: AppService}, children: [
   {path: 'home', component: HomeComponent},,
   {path: 'faq', component: FaqComponent},
   {path: 'about', component: AboutComponent},
   {path: 'contact', component: ContactComponent},
]}

在 AppServices 中我有以下功能:

  resolve(): Promise<any> {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log('RESOLVING');
        resolve();
      }, 5000);

    })
  }

这不起作用:在调用resolve 之前显示用户导航到的页面。

问题:如何定义在应用准备好之前必须解析的函数?无论用户导航到//foo /foo/bar,都必须调用此函数,并且只能在用户第一次导航到应用程序时调用。

【问题讨论】:

    标签: angular promise


    【解决方案1】:

    添加到应用提供商:

    {
            provide: APP_INITIALIZER,
            useFactory: startupServiceFactory,
            deps: [ Session ],
            multi: true,
        },
    

    地点:

    export function startupServiceFactory(startupService: Session): Function {
        return () => startupService.initialize();
    }
    

    将 startupService.initialize() 替换为您的方法。 deps 包含您的服务所具有的任何依赖项,可以省略。

    示例:

     async initialize(): Promise<any> {
            try {
                if (!environment.production) {
                    this.user = await this.service.init();
                    this.role = this.user.role;
                    this.lang = this.user.lang;
                    this.translate.use(this.user.lang);
                    this.registerLocale();
                    this.navigate();
                    return;
                }
                this.router.navigateByUrl('/');
            } catch (err) {}
        }
    

    【讨论】:

    • 谢谢。 “初始化”函数必须返回一个承诺,对吧?
    • 这正是我想要的。谢谢!非常感谢!
    • 这只会在应用程序初始化时调用一次,而不是每次用户导航到站点时。
    • 会的。上面的示例是让我的用户自动登录到我的应用程序,以防他们的会话处于活动状态。它按预期工作。
    【解决方案2】:

    您可以使用 canActivate gurard,它可以在路由上返回布尔值的 Observable。

    import { Injectable } from '@angular/core';
    import { CanActivate, Router }    from '@angular/router';
    import { Observable } from 'rxjs/Observable';
    
        @Injectable()
        export class AuthGuard implements CanActivate {
          constructor(private router: Router) { }
    
          canActivate(): Observable<boolean> {
                //Ajax call and other logic
                return Observable.of(true)
          }
        }
    
    
    
    {path: '', canActivate: [AuthGuard], children: [
       {path: 'home', component: HomeComponent},,
       {path: 'faq', component: FaqComponent},
       {path: 'about', component: AboutComponent},
       {path: 'contact', component: ContactComponent},
    ]}
    

    【讨论】:

    • 这种方法可行,但对我来说看起来有点 hacky。我不认为 canActivate 是为这个用例构建的。我还认为每次路线更改时都会调用 canActivate(可能是错误的)
    • 我认为每次用户导航到站点时都不会调用 APP_INITIALIZER。
    猜你喜欢
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2020-02-03
    • 2017-05-31
    相关资源
    最近更新 更多