在解析服务之前加载角组件

问题描述

我正在尝试从后端使用API​​加载应用程序级变量,该变量将在整个应用程序中使用。出于同样的原因,我使用了解析器,但是在加载任何组件之前仍未加载该服务,这是我的代码

pub.global.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { CustomUrlBaseService } from './auth/customurlbase';
import { Observable,Subject } from 'rxjs';
import { Resolve } from '@angular/router';

@Injectable()
export class PubService extends CustomUrlBaseService implements Resolve<any> {
    appRoot = '/api/pub';
    StoreData = '';
    private loadPub = new Subject<any>();
    loadPubObservable$ = this.loadPub.asObservable();
    constructor(private http: HttpClient) {
      super();
    }
    resolve() {
      this.GetStoreData();
    }
    GetStoreData() {
      this.GetData().subscribe(res => {
        this.StoreData = res;
        console.log(res);
      })
    }
   GetData(): Observable<any> {
    const url = (`${this.baseURL + this.appRoot}/GetStoreData`);
    return this.http.get(url);
  }
}

pub-footer.component.ts

import { PubService } from './../../services/pub.global.service';
import { Component,OnInit } from '@angular/core';

@Component({
  selector: 'app-pub-footer',templateUrl: './pub-footer.component.html',styleUrls: ['./pub-footer.component.scss']
})
export class PubFooterComponent implements OnInit {
  copyrightinfo;
  constructor(private pubService: PubService) { }

  ngOnInit() {
    console.log(this.pubService.StoreData);
    const FooterData = this.pubService.StoreData;
    this.copyrightinfo = FooterData['copyrightinfo'];
  }
}

app.routing.ts

{
    path: '',component: PubLayoutComponent,loadChildren: () => import('./views/pub/pub.module').then(m => m.PubModule),data: { title: '' },resolve: { items: PubService }
  },

我还尝试了app_initializer,现在我的api被调用了两次,但在加载组件之前没有被调用: 在我的模块中。

PubService,{
      provide: APP_INITIALIZER,useFactory: initApp,deps: [PubService],multi: true
    }
export function initApp(initService: PubService) {
  return () => {
    initService.GetStoreData();
  }
}

我的总体想法是仅通过一个api调用加载Header和Footer信息,并将其存储在服务变量中,然后从header和footer组件中访问此json对象。我什至怀疑这种方法是否正确。

解决方法

您可以尝试这种设置。

第一个集中式存储库服务,因此您可以控制标头,路径和安全性(如果需要,也可以在此处进行POST,PUT,DELETE):-

repository.service.ts

@Injectable({
  providedIn: 'root'
})
export class RepositoryService {
  constructor(private http: HttpClient) { }

  public getData = (route: string) => {
    return this.http.get(this.createCompleteRoute(route,environment.endPoint),this.generateHeaders());
  }
  private createCompleteRoute = (route: string,envAddress: string) => {
    return `${envAddress}/${route}`;
  }

  private generateHeaders = () => {
    return {
      headers: new HttpHeaders({
        'Content-Type': 'application/json','Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': 'GET,POST,PATCH,PUT,DELETE,OPTIONS','Access-Control-Allow-Headers': 'Origin,Content-Type,X-Auth-Token'
      })
    };
  }
}

然后获取并设置数据的服务:-

store-config.service.ts

@Injectable()
export class StoreConfigService {
    protected config: StoreConfig;
    constructor(private repoService: RepositoryService) { }

    public load(): Observable<StoreConfig> {
        return new Observable(observer => {
            if (this.config) {
                observer.next(this.config);
                observer.complete();
            } else {        
               this.repoService.getData(`<url here>`)
                        .subscribe(res => {
                            this.config = res as StoreConfig;
                            observer.next(this.config as StoreConfig);
                            observer.complete();
                        });
                }
            }
        });
    }
}

最后将其捆绑在组件中(或者您希望访问商店数据的位置,后者每次访问只会调用一次实际的API,因此您可以在不增加开销的情况下随意调用它多次):->

constructor(public storeConfigService: StoreConfigService) { 
   // Here or in onInit ... or where ever
    this.storeConfigService.load()
    .subscribe(res => { <Do your stuff here> });
}

,

将主题更改为BehaviorSubject

BehaviorSubject