0

所以我试图通过一个服务连接两个组件,LoaderComponentAppComponent使用LoaderService,以便当应用程序获取数据时,一个加载器会出现。但是,当我尝试使用 anEventEmitter向组件发出更改时,它们不会得到更改,但是当服务订阅自身时,它可以获得更改

加载服务.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订阅者那里获得事件

4

2 回答 2

1

首先,EventEmitters 和 Outputs 不属于服务。

我将重构以使用主题并通过将其设为私有并公开公开可观察对象来保护您的主题,这限制了您的主题状态可以修改的方式,这不是必需的,但通常被认为是良好的做法:

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 个加载器接收相同服务的不同副本,因为它们各自提供并注入自己的服务,因此它们不会看到彼此的事件。

为了解决这个问题,您改为在应用程序组件中提供(而不是在加载程序组件中),以便它们具有相同的服务副本,因为这样父级正在提供它们每个注入的服务。如果你在 app 组件和 loader 组件中都提供,它们都会收到不同的副本。

如果您在根(模块级别)提供,那么注入服务的每个组件(并且不提供它自己的)都将收到该服务的相同副本。

提供服务的适当位置取决于您的应用程序的需求和特定服务的功能。

于 2019-04-30T19:08:44.967 回答
1

您需要LoaderService在某些组件中使用 Angular 来创建它,如果我们不使用任何服务,那么 Angular 会自动丢弃它。注入LoaderService应用程序组件,如下所示:

constructor(private _loadService: LoaderService) {}然后你会看到console.log().

此外,建议在服务中使用来自 Rxjs 的 Subject 或 Behavior Subject 而不是 Output。

于 2019-04-30T19:16:06.617 回答