因此,我尝试通过LoaderComponent
和AppComponent
和LoaderService
服务连接两个组件,以便在应用程序获取数据时显示加载程序。但是,当我尝试使用EventEmitter
向组件发出更改时,它们没有得到更改,但是当服务订阅时
本身,它可以获取更改
LoaderService.ts
import { EventEmitter, Injectable } from '@angular/core';
@Injectable()
class LoaderService {
@Output change: EventEmitter<number> = new EventEmitter<number>();
private state: number = 0;
constructor() {
this.change.subscribe(state => console.log(state));
this.setState(1)
}
setState(state: number) {
this.state = state;
this.change.emit(this.state);
}
}
// Shows state when but outside of the service event is not detected, also tried EventEmitter from from events
我希望将事件从LoaderService
传递到订阅者
答案 0 :(得分:1)
第一件事,EventEmitters and Outputs don't belong in a service.
我将重构主题的使用方式,并通过将其设为私有并公开可见的方式来保护您的主题,这限制了如何修改主题状态,这不是必需的,但通常被认为是一种很好的做法:
import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
@Injectable()
class LoaderService {
private change: Subject<number> = new Subject<number>();
change$: Observable<number> = this.change.asObservable();
private state: number = 0;
constructor() {
this.change$.subscribe(state => console.log(state));
this.setState(1)
}
setState(state: number) {
this.state = state;
this.change.next(this.state);
}
}
第二,这可能与您提供服务的方式有关。如果您有类似以下的应用程序组件模板:
<loader-component></loader-component>
<loader-component></loader-component>
并排有2个加载程序组件,并且加载程序组件具有以下提供程序数组:
providers: [LoaderService]
然后,这两个加载器将接收相同的服务的不同副本,因为它们各自提供并注入自己的服务,因此它们将不会看到彼此的事件。
要解决此问题,请改为在app组件中提供(而不是在loader组件中),以使它们具有相同的服务副本,因为父级将提供它们每个注入的服务。如果要同时提供应用程序组件和加载器组件,则它们都将收到不同的副本。
如果您在根目录(模块级别)提供,则每个注入服务的组件(不提供它自己的组件)将收到该服务的相同副本。
提供服务的适当位置取决于您应用的需求和特定服务的功能。
答案 1 :(得分:1)
您需要在angular的某些组件中使用LoaderService
来创建它,如果我们不使用任何服务,那么angular会自动将其丢弃。将LoaderService
注入应用组件中,如下所示:
constructor(private _loadService: LoaderService) {}
,然后您将看到console.log()
。
此外,建议在服务中使用Rxjs中的Subject或Behavior Subject,而不是Output。