有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]

Posted

技术标签:

【中文标题】有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]【英文标题】:Having 2 or more components subscribe to a cold Observable provided by an Injectable [duplicate] 【发布时间】:2017-11-16 04:50:41 【问题描述】:

对不起,如果这是微不足道的。

我是 Angular 4 的新手,我正在努力解决一个看似简单的问题:有 2 个或更多组件订阅由(登录)Injectable 提供的Observable

我的目标是:

    视图调用component1 上的事件 component1 将调用 login.service 上的方法 login.service 将进行 REST 调用 响应是“广播”使用.next() component1component2 会做出相应的反应

当只有一个组件时,这非常有效,但是当我将另一个组件 subscribe()s 引入到 Observable 时,第二个组件只会在开始时收到通知(即:它只接收一条消息)而 @ 987654333@ 继续按预期工作并接收所有消息。

我最初将SubjectBehaviorSubjectasObservable() 方法一起使用,但后来又退回到普通的Observable,结果相似。

这里有一个 sn-p 来帮助演示:

login.service:

@Injectable()
export class LoginService 

    private _loggedIn = new BehaviorSubject<booelan>(false);
    public loggedIn$ = this._loggedIn.asObservable();


    login() 
        // call API service
        this._loggedIn.next(true);
    
 

component1:

@Component(
    selector: 'app-test1',
    template: `<button (click)="login()"`,
    providers: [ LoginService ]
)

export class AppTest1Component 
    subscription: Subscription;
    observer: Observer;

    constructor(private loginService: LoginService) 

    ngOnInit() 
        this.subscription = this.loginService.loggedIn$.subscribe(
            state =>  console.log('got event!', state); ,
            error =>  console.log('Error:', error),
            () =>  console.log('Complete'); 
        );
    

    ngOnDestroy() 
        this.subscription.unsubscribe();
   

component2:

@Component(
    selector: 'app-test2',
    template: `<button (click)="login()"`,
    providers: [ LoginService ]
)

export class AppTest2Component 
    subscription: Subscription;
    observer: Observer;

    constructor(private loginService: LoginService) 

    ngOnInit() 
        this.subscription = this.loginService.loggedIn$.subscribe(
            state =>  console.log('got event!', state); ,
            error =>  console.log('Error:', error),
            () =>  console.log('Complete'); 
        );
    

    ngOnDestroy() 
        this.subscription.unsubscribe();
   

让多个组件订阅可能由服务提供的Observable 并接收所有消息的最简单方法是什么?

此处发布的问题:Angular - shared service between components doesn't work 与 Observables 和 Subscriptions 无关。

【问题讨论】:

这个问题可能与 observables 无关,但它解决了同样的问题。请阅读答案并在您的应用中尝试。 你太棒了。很抱歉没有花时间仔细阅读回复。我有隧道视野。 发生在我们最好的人身上:-) 【参考方案1】:

正如 echonax 所解释的,您的问题似乎与 this topic 有关。

通过将 LoginService 添加为这两个组件的提供者,您实际上是在创建所述服务的 2 个实例。

@Component(
    selector: 'app-test2',
    template: `<button (click)="login()"`,
    providers: [ LoginService ] /* you are creating a new instance of the service here /*
)

如果你想拥有相同的实例,或者所谓的共享服务,你必须在它们所在的模块中声明提供者,并在组件中删除提供者:

@NgModule(
    ...
    providers: [LoginService],
    ...
)

如果您提到的两个组件位于单独的模块中,您必须在一个模块中将服务声明为提供者,然后将此模块导入另一个模块:

/* NgModule of the Module2 */
@NgModule(
    imports: [
    Module1], /* you import the module which has the service as provider */
    providers: [] /* Really important point here, you have to leave providers blank or at least with no reference to the shared service, or you will create a new instance of the said service */
   ...
)

我不完全确定它会解决您的问题,但我几乎可以肯定,根据您提供的代码,无论如何您都必须在您的应用中使用共享服务。

【讨论】:

你说的都是对的。谢谢 Echonax 和 nvkfr。我整天都在为此苦苦挣扎。我已经在我的@NgModules 中声明了该服务,但是正如您在我的 sn-ps 中看到的那样,我愚蠢地在每个组件中实例化了一个新副本。一旦我从两个组件中删除了提供程序,一切都运行良好。谢谢!

以上是关于有 2 个或更多组件订阅由 Injectable 提供的冷 Observable [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Websocket事件仅由一个组件捕获

我们可以直接在Angular 4组件中订阅RxJs主题吗?

无法订阅 BehaviorSubject

如何将 2 个或多个 Http 隧道(例如 ngrok)与 2 个或多个 .net 不同的应用程序(需要处理图形 api 的不同订阅)一起使用?

ionic 2,刷新带有 2 个或更多徽标的模态页面

Angular 2 @Injectable 似乎不起作用