角度2:可观察/订阅未触发

SrAxi

我已经在我的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:考虑到IboDetailsGeneralApp结构的下层,IboDetailsGeneral子级也是如此IBOsNavigationElement

这就是为什么我添加NavigationElementsServiceIBOsNavigationElement的模块中的原因:

NavigationModuleIBOsNavigationElement的模块

@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加入到providersNavigationModule,所以的服务的权利只有一个实例?然后,以下链接中说明的问题不会发生: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()仍未触发。

使用BehaviorSubjectv2:

我尝试了这种方法: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:

在整个网络上进行研究后,我们进行了更多拼命尝试的示例...

使用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);
    }
}

结果:与以前的BehaviorSubject尝试相同...绝望情绪正在上升...

更新3:

以防万一,我想确保这NavigationElementsService是一个单例

export class NavigationModule {
    static forRoot() {
        return {
            ngModule: NavigationModule,
            providers: [NavigationElementsService]
        };
    }
}

导入时:

imports: [
        NavigationModule.forRoot()
       ]

结果:与往常一样的问题,subscribe()没有触发,但是至少我知道存在一个实例NavigationElementsService

泰勒·詹宁斯

我认为问题是您的Subject类型为With Subject,在事件触发后进行预订的任何组件都不会收到值。要将先前的值重播给后期订阅者,请使用BehaviorSubjectReplaySubject代替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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章