SrA*_*Axi 17 angular2-observables angular
我在我的应用程序中多次这样做了.它很简单,它应该工作......但这次它没有.
我的问题:
我在组件A中调用服务中的方法,我的组件B已订阅但不响应也不接收任何内容.subscribe()没有触发!
导航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);
}
}
Run Code Online (Sandbox Code Playgroud)
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();
}
}
Run Code Online (Sandbox Code Playgroud)
该组件触发服务的方法: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() {
}
}
Run Code Online (Sandbox Code Playgroud)
该组件已订阅,应列出并接收数据...
让我们理清DI:考虑到IboDetailsGeneral应用程序结构中的较低层,所以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
]
})
Run Code Online (Sandbox Code Playgroud)
安慰:
调用updateIBOsNavigation功能
updateIBOsNavigation"95"
再次呼叫updateIBOsNavigation功能
updateIBOsNavigation"test"
这个控制台结果告诉我:
我的测试:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
结果:通话时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);
}
}
Run Code Online (Sandbox Code Playgroud)
结果:它进入subscribe()初始化但是当我打电话时updateIBOsNavigation(),subscribe()仍然没有触发.
使用BehaviorSubjectv2:
我尝试了这种方法:behaviourSubject in angular2,它是如何工作的以及如何使用它
@Injectable()
export class NavigationElementsService {
public updateIBOsNavigation$: Subject<string> = new BehaviorSubject<string>(null);
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigation$.next(navigationData);
}
}
Run Code Online (Sandbox Code Playgroud)
结果:与之前的申请相同BehaviorSubject.
更新2:
在整个网络上进行研究后,更多的绝望尝试样本......
使用BehaviorSubjectv3:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
结果:与之前的BehaviorSubject尝试相同......绝望正在上升......
更新3:
为了以防万一,我想确保它NavigationElementsService是一个单身人士:
export class NavigationModule {
static forRoot() {
return {
ngModule: NavigationModule,
providers: [NavigationElementsService]
};
}
}
Run Code Online (Sandbox Code Playgroud)
并在导入时:
imports: [
NavigationModule.forRoot()
]
Run Code Online (Sandbox Code Playgroud)
结果:一如既往的问题,subscribe()没有触发,但至少我知道有一个实例NavigationElementsService.
Tyl*_*ngs 35
我认为问题是你的Subject类型With Subject,在事件被触发后订阅的任何组件都不会收到值.要将之前的值重播给后期订阅者使用BehaviorSubject或ReplaySubject代替Subject.
有关http://reactivex.io/documentation/subject.html中不同主题类型的更多信息
行为主体
当观察者订阅BehaviorSubject时,它首先发出源Observable最近发出的项(或者如果尚未发出种子/默认值),然后继续发出源Observable稍后发出的任何其他项( S).
ReplaySubject
无论观察者何时订阅,ReplaySubject都会向任何观察者发出源Observable发出的所有项目.
A BehaviorSubject在设置时确实需要默认值.所以你需要创建一些有价值的东西:
updateIBOsNavigationSubject = new BehaviorSubject<any>('');
updateIBOsNavigation$ = this.updateIBOsNavigationSubject.asObservable();
updateIBOsNavigation(navigationData) {
log.d('updateIBOsNavigation', JSON.stringify(navigationData));
this.updateIBOsNavigationSubject.next(navigationData);
}
Run Code Online (Sandbox Code Playgroud)
A ReplaySubject不需要默认值.
编辑
使用共享服务时,确保仅在根模块上提供服务也很重要.如果提供多个位置,则组件可能无法获得相同的实例.即使服务是在根级别提供的,如果根级别和组件之间的模块提供服务,则新实例将在依赖注入树的该分支下发送.
希望这可以帮助.
小智 5
当我们在“提供者”中包含服务时,将对其进行实例化,并在其组件及其子组件之间维持此状态。
而且,如果我们在两个组件提供程序数组中都包含该服务,则不再跟随单例。状态将是独立的,并且不会在它们之间共享。
因此,仅在父组件或根组件中包括您的服务。
我也遇到了这个问题,并在这里/sf/answers/2662400891/的帮助下解决了该问题。
| 归档时间: |
|
| 查看次数: |
17729 次 |
| 最近记录: |