我有2个组件,并且在这2个组件之间共享一项服务,比方说ComponentA和ComponentB。应用程序工具栏(组件A)中的一个组件和组件B中的另一个组件通过路由模块进行路由。这是HTML:
<a></a>
<router-outlet></router-outlet>
之所以这样,是因为我想始终将工具栏固定在顶部。 在组件A的HTML中,我可以选择应用程序的语言。在组件BI中,某些内容来自后端,具体取决于所选语言。我希望当用户更改语言时,内容来自服务器以进行呈现。我正在使用服务来调用后端并呈现新内容。我的问题来了,对服务器的调用已经完成并且可以,但是它从未进入订阅功能。我尝试使用共享模块(带有或不带有forRoot()),尝试使服务成为模块的提供程序,然后将模块(AppRoutingModule)导入另一个模块(AppModule)中。在这一刻,我到达了“没有服务提供者”的地步。控制台错误。服务和组件的代码: 服务:
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
get content() {
return this.sectionsSubject.asObservable();
}
}
AppModule
@NgModule({
imports:[AppRoutingModule]
})
export class AppModule {}
AppRoutingModule
export function SharedServiceFactory(http: HttpClient){
return new SharedServiceFactory(http);
}
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [
{
provide: SectionService,
useFactory: SectionServiceFactory,
deps: [HttpClient]
}
]
})
export class AppRoutingModule {}
组件A:
@Component({
selector: "a",
templateUrl: ".a.component.html",
styleUrls: ["./a.component.scss"]
})
export class AComponent implements OnInit {
constructor(
public authentificationService: AuthenticationService,
private languagesService: LanguagesService,
private sharedService: SharedService
) {
}
ngOnInit() {
//other logic;
}
updateLanguage(event) {
// other logic;
this.sharedService.load();
}
ComponentB
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content.subscribe(s => {
// logic
});
}
如何使SharedService具有单个实例,或者可以将一个模块包含在另一个模块中?
答案 0 :(得分:0)
尝试在您的服务中执行此操作:
@Injectable({ providedIn: 'root' })
并从 AppRoutingModule 中删除此服务的提供。
如果您使用providedIn: 'root'
,则无需在其他地方提供它。它将在Angular树的顶部注入服务,因此您将始终拥有相同的实例。它的另一个好处-它使服务可以摇树。
答案 1 :(得分:0)
首先将服务导入AppModule:
AppModule
@NgModule({
imports:[AppRoutingModule],
providers: [SharedService]
})
export class AppModule {}
OR:
@Injectable({提供者:'root'}) 导出类SharedService扩展了GlobalHttpService { ... }
然后,您不必在SharedService中创建方法来返回Observable事件,只需在构造函数中创建一次属性和实例即可。
SharedService
@Injectable()
export class SharedService extends GlobalHttpService<HomeSection> {
private sectionsSubject: BehaviorSubject<HomeSection[]>;
public content$: Observable<HomeSection[]>;
constructor(private http: HttpClient) {
super("api/path", new GlobalSerializer(HomeSection), http);
this.sectionsSubject = new BehaviorSubject<HomeSection[]>([]);
this.content$ = this.sectionsSubject.asObservable();
}
load() {
this.list().subscribe(res => {
this.sectionsSubject.next(res);
});
}
}
最后在组件B中:
@Component({
selector: "app-b",
templateUrl: "./b.component.html",
styleUrls: ["./b.component.scss"]
})
export class BComponent implements OnInit {
constructor(
private sharedService: SharedService,
) {}
ngOnInit() {
this.sharedService.load();
this.sharedService.content$.subscribe(s => {
// logic
});
}