让 2 个或更多组件订阅由 Injectable 提供的冷 Observable

Having 2 or more components subscribe to a cold Observable provided by an Injectable

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

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

我的目标是:

  1. 视图在 component1
  2. 上调用事件
  3. component1 将在 login.service
  4. 上调用一个方法
  5. login.service 将进行 REST 调用
  6. 响应是 "broadcast" 使用 .next()
  7. component1component2 将做出相应反应

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

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

这里有一个片段可以帮助演示:

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 并接收所有消息的最简单方法是什么?

此处发布的问题: 与 Observables 和订阅无关。

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

通过将 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 */
   ...
})

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