我已经在我的App中多次进行了此操作。很简单,它应该可以工作...但是这次没有。
我的问题:
我正在从组件A调用服务中的方法,我的组件B已订阅,但不响应也不接收任何内容。subscribe()
没有触发!
navigation-elements.service.ts
@Injectable()
export class NavigationElementsService {
updateIBOsNavigation$: Observable<any>;
private updateIBOsNavigationSubject = new Subject<any>();
constructor() {
this.updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
}
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
IboDetailsGeneral
零件
export class IboDetailsGeneral implements OnInit, OnDestroy {
id: string;
private sub: any;
constructor(private route: ActivatedRoute, private iboService: IBOsService, private navigationService: NavigationElementsService) {
this.sub = this.route.params.subscribe(params => {
this.id = params['id'];
console.log('CALLING updateIBOsNavigation FUNCTION');
this.navigationService.updateIBOsNavigation(this.id);
});
}
ngOnInit() {
console.log('CALLING updateIBOsNavigation FUNCTION AGAIN');
this.navigationService.updateIBOsNavigation('test');
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
该组件触发服务的方法:updateIBOsNavigation
。
IBOsNavigationElement
零件
export class IBOsNavigationElement implements OnInit {
private id: string;
constructor(private navigationService: NavigationElementsService) {
this.navigationService.updateIBOsNavigation$.subscribe((navigationData) => {
log.d('I received this Navigation Data:', JSON.stringify(navigationData));
this.id = navigationData;
}
);
}
ngOnInit() {
}
}
此组件已订阅,应该列出并接收数据...
让我们整理一下DI:考虑到IboDetailsGeneral
App结构的下层,IboDetailsGeneral
的子级也是如此IBOsNavigationElement
。
这就是为什么我添加NavigationElementsService
到IBOsNavigationElement
的模块中的原因:
NavigationModule
是IBOsNavigationElement
的模块
@NgModule({
imports: [
// A lot of stuff
],
declarations: [
// A lot of stuff
IBOsNavigationElement
],
exports: [
// A lot of stuff
],
providers: [
NavigationElementsService
]
})
安慰:
呼叫updateIBOsNavigation功能
updateIBOsNavigation“ 95”
重新调用IBOsNavigation功能
updateIBOsNavigation“测试”
该控制台结果告诉我:
我的测试:
IBOsNavigationElement
(侦听器)中调用随机方法,并且与服务的通信良好。NavigationElementsService
加入到providers
在NavigationModule
,所以的服务的权利只有一个实例?然后,以下链接中说明的问题不会发生:Angular 2可观察的订阅未触发对于我的“文字墙”,我真的感到很抱歉,但在这一点上,我有点绝望。
感谢您的帮助!
更新1:
在第一个答案之后,我尝试了几件事...
使用ReplaySubject
:
@Injectable()
export class NavigationElementsService {
public updateIBOsNavigation$ = new ReplaySubject();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigation$.next(navigationData);
}
}
结果:调用时updateIBOsNavigation()
,subscribe()
仍未触发。
使用BehaviorSubject
:
@Injectable()
export class NavigationElementsService {
updateIBOsNavigationSubject = new BehaviorSubject<any>('');
updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
结果:它subscribe()
在初始化时进入,但是当我调用时updateIBOsNavigation()
,subscribe()
仍未触发。
使用BehaviorSubject
v2:
我尝试了这种方法:angular2中的behaviourSubject,它如何工作以及如何使用它
@Injectable()
export class NavigationElementsService {
public updateIBOsNavigation$: Subject<string> = new BehaviorSubject<string>(null);
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigation$.next(navigationData);
}
}
结果:与的先前应用程序相同BehaviorSubject
。
更新2:
在整个网络上进行研究后,我们进行了更多拼命尝试的示例...
使用BehaviorSubject
v3:
@Injectable()
export class NavigationElementsService {
updateIBOsNavigation$: Observable<any>;
updateIBOsNavigationSubject = <BehaviorSubject<any>> new BehaviorSubject([]);
constructor() {
this.updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
}
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation()', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
}
结果:与以前的BehaviorSubject
尝试相同...绝望情绪正在上升...
更新3:
以防万一,我想确保这NavigationElementsService
是一个单例:
export class NavigationModule {
static forRoot() {
return {
ngModule: NavigationModule,
providers: [NavigationElementsService]
};
}
}
导入时:
imports: [
NavigationModule.forRoot()
]
结果:与往常一样的问题,subscribe()
没有触发,但是至少我知道存在一个实例NavigationElementsService
。
我认为问题是您的Subject
类型为With Subject
,在事件触发后进行预订的任何组件都不会收到值。要将先前的值重播给后期订阅者,请使用BehaviorSubject
或ReplaySubject
代替Subject
。
有关不同主题类型的更多信息,请参见http://reactivex.io/documentation/subject.html
行为主体
当观察者订阅了BehaviorSubject时,它首先发出源Observable最近发出的项目(如果尚未发出,则为种子/默认值),然后继续发出后来源Observable()发出的任何其他项目。 s)。
重播主题
ReplaySubject向观察者发出源Observable发出的所有项目,无论观察者何时订阅。
一个BehaviorSubject
不设置起来的时候,需要一个默认值。因此,您需要使用某种值来创建它:
updateIBOsNavigationSubject = new BehaviorSubject<any>('');
updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
AReplaySubject
不需要默认值。
编辑
使用共享服务时,确保仅在根模块上提供该服务也很重要。如果提供多个位置,则组件可能不会获得相同的实例。即使该服务是在根级别提供的,如果在根级别和您的组件之间的模块提供了该服务,则将在依赖注入树的该分支下发送一个新实例。
希望这可以帮助。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句