【问题标题】:How to load a global config file to Angular component before the view is loaded如何在加载视图之前将全局配置文件加载到 Angular 组件
【发布时间】:2022-11-24 23:56:23
【问题描述】:

我有一个如下所示的全局配置文件:

{
  "options": {
    "pages": 5,
    "paginator": true,
    "rows": [
      "5",
      "10",
      "15",
      "20",
      "25",
      "30",
      "40",
      "50",
      "100"
    ],
    "perPage": 10,
    "sorting": true,
    "selection": true
  }
}

我通过ngOnit() 中的服务调用此文件,如下所示:

  ngOnInit() {
     this.getGlobalSettings();
  }

  getGlobalSettings(){
    const providerSubscription = this.leaveApplicationService.getGlobalSettings().subscribe(res => {
      this.pageSettings = res;
      },
      error => {
        console.log(error);
      },
      () => {
      });
   this.subscriptionCollection.add(providerSubscription);
  }

我在 HTML 文件中使用这些设置,但似乎配置仅在视图初始化后才加载。因此,当我尝试在视图中访问 pageSettings.options 时会抛出错误。

如何解决这个问题并在应用程序初始化后立即加载设置,以便它可用于所有组件?

【问题讨论】:

  • 您的 leaveApplicationService 是如何提供的?您也可以分享 Service + getGlobalSettings() 方法的代码吗?

标签: angular typescript


【解决方案1】:

如果您的配置文件嵌入到您的应用程序中, 您可以将配置文件导出为 Injectable

在 app.conf.ts 中

import { Injectable } from '@angular/core';

@Injectable()
export class APPCONFIG {
  "options" = {
    "pages": 5,
    "paginator": true,
    "rows": [
      "5",
      "10",
      "15",
      "20",
      "25",
      "30",
      "40",
      "50",
      "100"
    ],
    "perPage": 10,
    "sorting": true,
    "selection": true
  }
}

并将其直接导入到您的服务/组件中

import { APPCONFIG } from 'src/app/app.conf';

 constructor(private appConf: APPCONFIG) {
     console.log(this.appConf.options);
 }

就像 APPCONFIG 是可注入的一样,不要忘记在您的应用程序或组件中将其声明为提供者

providers: [
  APPCONFIG
] 

【讨论】:

  • 我用过这个,但我收到一个错误 Uncaught (in promise): Error: Can't resolve all parameters for MyComponent: ([object Object], [object Object],
  • 是的,就像它是可注射的一样,您还必须在组件或 app.component.ts 中将 APPCONFIG 声明为提供者
  • 我将这一点添加到我的回复中
  • 非常感谢。现在错误消失了。但是由于某种原因我得到了一个空对象。
  • 如果你做一个console.log(this.appConf);对象是空的?
【解决方案2】:

如果组件是基于路由加载的,你可以查看下面的文章

https://javascript.plainenglish.io/angular-resolver-for-prefetching-data-angular-guards-resolve-40fda257d666

【讨论】:

    【解决方案3】:

    您很可能想在 HTML 中使用异步管道 - 确保您的 HTML 在您的数据可用时立即显示。

    代码:

    pageSettings$: Observable<Settings>;
    
    constructor(private leaveApplicationService: LeaveApplicationService){}
    
    ngOnInit() {
      this.pageSettings$ = this.leaveApplicationService.getGlobalSettings();
    }
    

    HTML:

    <div *ngIf="pageSettings$ | async as pageSettings">
      Use your Data inside this DIV{{ pageSettings.x }}
    </div>
    

    如有必要,您还可以使用 div 来避免嵌套得更深。

    【讨论】:

      【解决方案4】:

      你可以加载东西可以激活,它将在组件加载之前加载所有内容。

      // You can use canActive  for loading all your require things, it will call your service method and then load main app component, So this way your assest will be aviable before thay use in any component.
      
      // Like i have Dashboard screen this is how i will use (in my case,i am checking user from server and checking token). i have AuthorizationGuard for this,  
      
      
      
      { path: 'dashboard/trips', component: TripsComponent, canActivate: [AuthorizationGuard] },
      
      // AuthorizationGuard  in my case here is how i am checking my user details through server api.
      
      
      @Injectable({
          providedIn: 'root'
        })
      export class AuthorizationGuard implements CanActivate {
          constructor(
              private authService: AuthService,
          ) {
          }
          canActivate(
              next: ActivatedRouteSnapshot,
              state: RouterStateSnapshot) {
              // i am checking user token 
              return this.authService.VerifyTokenWithNgrx()
                  .pipe(
                      map((data) => {
                          if (data.user != null) {
                          // saving user data. in your case you can impliment your logic here which you have shared in question.
                            this.authService.sendUserData(data.user);
                              moment.tz.setDefault(data.user.timeZone);
                              return true;
                          } else {
                              return false;
                          }
                      }),
                      catchError(() => {
                          return of(false);
                      })
                  );
          }
      }
      
      // after this your main component will load on screen and things will be available. 

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-27
        • 1970-01-01
        • 1970-01-01
        • 2019-10-14
        • 1970-01-01
        • 2015-04-18
        相关资源
        最近更新 更多