gpt4 book ai didi

Angular 2 : Observable/Subscription not triggering

转载 作者:太空狗 更新时间:2023-10-29 16:57:00 28 4
gpt4 key购买 nike

我已经在我的应用程序中多次这样做了。很简单,它应该可以工作...但这次不行。

我的问题:

我正在从组件 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 结构的较低层,因此 IboDetailsGeneralIBOsNavigationElement

这就是为什么我将 NavigationElementsService 添加到 IBOsNavigationElement 的模块中:

NavigationModuleIBOsNavigationElement 的模块

@NgModule({
imports: [
// A lot of stuff
],
declarations: [
// A lot of stuff
IBOsNavigationElement
],
exports: [
// A lot of stuff
],
providers: [
NavigationElementsService
]
})

控制台:

CALLING updateIBOsNavigation FUNCTION

updateIBOsNavigation "95"

CALLING updateIBOsNavigation FUNCTION AGAIN

updateIBOsNavigation "test"

这个控制台结果告诉我:

  • 正在调用该方法,因此没有提供者错误。 与服务的通信正常

我的测试:

  • 我尝试在 IBOsNavigationElement (监听器) 中调用随机方法,并且与服务的通信良好。
  • 唯一将 NavigationElementsService 添加到 providers 的地方是在 NavigationModule 中,所以只有一个服务实例对吗?然后,不会发生以下链接中说明的问题:Angular 2 observable subscription not triggering

我真的很抱歉我的“文字墙”,但在这一点上我有点绝望。

感谢任何帮助,谢谢!

更新 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:

我试过这种方法:behaviourSubject in angular2 , how it works and how to use it

@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 类型 使用 Subject,任何在事件触发后订阅的组件都不会收到值。要向迟到的订阅者重播以前的值,请使用 BehaviorSubjectReplaySubject 而不是 Subject

有关不同主题类型的更多信息,来自 http://reactivex.io/documentation/subject.html

Behavior Subject

When an observer subscribes to a BehaviorSubject, it begins by emitting the item most recently emitted by the source Observable (or a seed/default value if none has yet been emitted) and then continues to emit any other items emitted later by the source Observable(s).

ReplaySubject

ReplaySubject emits to any observer all of the items that were emitted by the source Observable(s), regardless of when the observer subscribes.

BehaviorSubject 在设置时确实需要默认值。所以你需要用某种值(value)来创建它:

updateIBOsNavigationSubject = new BehaviorSubject<any>('');
updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();

updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}

ReplaySubject 不需要默认值。

编辑

使用共享服务时,确保服务仅在根模块中提供也很重要。如果它在多个地方提供,那么组件可能不会获得相同的实例。即使服务是在根级别提供的,如果根级别和您的组件之间的模块提供服务,一个新实例将被发送到依赖注入(inject)树的那个分支。

希望这对您有所帮助。

关于 Angular 2 : Observable/Subscription not triggering,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43374331/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com