问题描述
我正在尝试从后端使用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