让 2 个或更多组件订阅由 Injectable 提供的冷 Observable
Having 2 or more components subscribe to a cold Observable provided by an Injectable
对不起,如果这是微不足道的。
我是 Angular 4 的新手,我正在努力解决一个看似简单的问题:让 2 个或更多组件订阅由(登录)[=14= 提供的 Observable
].
我的目标是:
- 视图在
component1
上调用事件
component1
将在 login.service
上调用一个方法
login.service
将进行 REST 调用
- 响应是 "broadcast" 使用
.next()
component1
和 component2
将做出相应反应
这在只有 1 个组件时非常有效,但是当我将 subscribe()
的另一个组件引入 Observable
时,第二个组件只会在一开始就得到通知(即:它只收到一条消息)而 component1
继续按预期工作并收到所有消息。
我最初将 Subject
和 BehaviorSubject
与 asObservable()
方法一起使用,但后来退回到普通 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 */
...
})
我不完全确定它会解决您的问题,但我几乎可以肯定,根据您提供的代码,您无论如何都必须在您的应用程序中使用共享服务。
对不起,如果这是微不足道的。
我是 Angular 4 的新手,我正在努力解决一个看似简单的问题:让 2 个或更多组件订阅由(登录)[=14= 提供的 Observable
].
我的目标是:
- 视图在
component1
上调用事件
component1
将在login.service
上调用一个方法
login.service
将进行 REST 调用- 响应是 "broadcast" 使用
.next()
component1
和component2
将做出相应反应
这在只有 1 个组件时非常有效,但是当我将 subscribe()
的另一个组件引入 Observable
时,第二个组件只会在一开始就得到通知(即:它只收到一条消息)而 component1
继续按预期工作并收到所有消息。
我最初将 Subject
和 BehaviorSubject
与 asObservable()
方法一起使用,但后来退回到普通 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
并接收所有消息的最简单方法是什么?
此处发布的问题:
正如 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 */
...
})
我不完全确定它会解决您的问题,但我几乎可以肯定,根据您提供的代码,您无论如何都必须在您的应用程序中使用共享服务。