EventEmitter 的 Emit 方法不向订阅者发送值
Emit method of EventEmitter not emitting values to subscribers
所以我试图通过服务连接两个组件,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
发送给订阅者
首先,
我将重构以使用主题并通过将其设为私有并公开 public 可观察对象来保护您的主题,这限制了您的主题状态的修改方式,这不是必需的,但通常被认为是好的做法:
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]
然后这 2 个加载器接收相同服务的不同副本,因为它们各自提供并注入自己的服务,因此它们不会看到彼此的事件。
为了解决这个问题,您改为在应用程序组件中提供(而不是在加载程序组件中),以便它们具有相同的服务副本,因为这样父级就会提供它们每个注入的服务。如果您同时提供应用程序组件和加载器组件,它们都会收到不同的副本。
如果您在根目录(模块级别)提供服务,那么注入该服务(并且不提供它自己的服务)的每个组件都将收到该服务的相同副本。
提供服务的适当位置取决于您应用的需求和特定服务的功能。
您需要在某些组件中使用 LoaderService
来为 angular 创建它,如果我们不使用该服务, angular 将自动丢弃它。在应用程序组件中注入 LoaderService
,如下所示:
constructor(private _loadService: LoaderService) {}
然后你会看到 console.log()
.
此外,建议使用 Rxjs 中的 Subject 或 Behavior Subject 而不是服务中的 Output。
所以我试图通过服务连接两个组件,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
发送给订阅者
首先,
我将重构以使用主题并通过将其设为私有并公开 public 可观察对象来保护您的主题,这限制了您的主题状态的修改方式,这不是必需的,但通常被认为是好的做法:
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]
然后这 2 个加载器接收相同服务的不同副本,因为它们各自提供并注入自己的服务,因此它们不会看到彼此的事件。
为了解决这个问题,您改为在应用程序组件中提供(而不是在加载程序组件中),以便它们具有相同的服务副本,因为这样父级就会提供它们每个注入的服务。如果您同时提供应用程序组件和加载器组件,它们都会收到不同的副本。
如果您在根目录(模块级别)提供服务,那么注入该服务(并且不提供它自己的服务)的每个组件都将收到该服务的相同副本。
提供服务的适当位置取决于您应用的需求和特定服务的功能。
您需要在某些组件中使用 LoaderService
来为 angular 创建它,如果我们不使用该服务, angular 将自动丢弃它。在应用程序组件中注入 LoaderService
,如下所示:
constructor(private _loadService: LoaderService) {}
然后你会看到 console.log()
.
此外,建议使用 Rxjs 中的 Subject 或 Behavior Subject 而不是服务中的 Output。