我知道这个问题已被问了很多次,但我已经查看了stackoverflow上的大部分答案,没有回答我的问题。我试图使用rxjs observable复制角度2+中的发射/广播行为。我已经编写了一个角度库,并且库需要向库的用户(一些角度4应用程序)广播关于操作成功/失败的信息。我已经编写了一个广播服务。当我尝试从库中广播并订阅用户的角度应用程序时,我总是返回BehaviorSubject的初始值而不是最新的值。我调试它并发现在重新路由期间(使用window.location.href,它将转到auth服务器然后使用window.loation.href返回到最后一个角度路由),组件正在重新创建并且广播服务重新启动实例化,因此广播以前的状态丢失。
我似乎无法找到解决此问题的方法。有没有办法在重新路由期间有效地广播/订阅?我愿意接受其他建议来实现相同的行为。谢谢!
更新:我确保我的服务是单身。我正在做的事情已经完成了@Tomasz Kula的建议。我想我知道这个问题。当我说改线时,我不清楚。我没有在角度应用中进行重新路由。我使用window.location.href访问不同的站点(某些身份验证服务器),然后如果登录成功,我尝试使用window.location.href再次将位置设置回最后一个角度路由。在这种情况下,我认为服务不是单身人士。
My Library
@NgModule({
imports: [CommonModule],
declarations: [
... library stuff
],
exports: [
... library stuff
],
providers: [
... library stuff without Broadcast Service
]
})
export class MyLibraryModule {
forRoot(): ModuleWithProviders {
return {
ngModule: MyLibraryModule,
providers: [BroadcastService]
}
}
}
Broadcast Service
@Injectable()
export class BroadcastService {
private _navItemSubject : BehaviorSubject<any> ;
private navItem$: Observable<any>;
constructor()
{
this._navItemSubject = new BehaviorSubject<any>(100);
this.navItem$ = this._navItemSubject.asObservable();
}
broadcast(type: string ,payload: any) {
this._navItemSubject.next({type , payload});
}
getNavItem()
{
return this.navItem$;
}
}
Another Service in Library
@Injectable()
export class AnotherService {
constructor(private broadcastService : BroadcastService)
{
}
// broadcasting to user's application using this method
broadcast()
{
if(success)
this.broadcastService.broadcast("success", somevalue);
else
this.broadcastService.broadcast("error", errorDesc);
}
}
Users can use the library like this:
in app.module
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
// this will add the BroadcastService to app providers
MyLibraryModule.forRoot()
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {
constructor() {}
}
component
export class appComponent implements OnInit, OnDestroy {
constructor(private broadcastService : BroadcastService)
{
}
ngOnInit() {
this.broadcastService.getNavItem().subscribe(item => {
// I get 100 here after rerouting instead of success or failure. It seems the component is recreated and broadcastservice is reinjected. Hence it has lost the state of what was already published
alert(" listening to broadcast");
})
}
}
答案 0 :(得分:2)
您需要将服务作为应用级单身人士提供。您可以将forRoot()方法添加到模块
@NgModule({
imports: [CommonModule],
declarations: [
... library stuff
],
exports: [
... library stuff
],
providers: [
... library stuff without Broadcast Service
]
})
export class MyLibraryModule {
forRoot(): ModuleWithProviders {
return {
ngModule: MyLibraryModule,
providers: [BroadcastService]
}
}
}
用户可以像这样使用库:
app.module中的
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
// this will add the BroadcastService to app providers
MyLibraryModule.forRoot()
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {
constructor() {}
}
在任何其他模块中
@NgModule({
declarations: [],
imports: [
CommonModule,
// this will add the library without the BroadcastService
MyLibraryModule
],
providers: [],
bootstrap: [],
})
export class OtherModule {
constructor() {}
}