Angular 组件订阅看不到调用 next() 的带有 Subject Observable 的服务

Angular Service with Subject Observable calling next() is not seen by Component subscriptions

我想从 Angular 服务中检索更新的对象值(借款人)。我在服务中创建了一个 RxJS Subject 以便多个组件可以订阅它并获取更新的值。

当我通过组件中提供的服务订阅主题时,我发现即使从 BorrowerService 调用 .next() 时也从未调用 onNext() 函数参数。

如果我确实在 BorrowerService class 中进行了订阅,我发现 .next() 按预期工作。似乎主题是调用 .next() 的服务 class 和组件之间的不同实例,因此没有获得该订阅。

这是对 Angular 服务或 Observable 理解的失败吗?如何在不知道何时调用 .next()?

的情况下更新服务中的值并被动获取组件中的更改

借款人-report.component.ts

@Component({
    ...
    providers:   [BorrowerService]
})
export class BorrowerReport {
    private borrower: Borrower;

    constructor(private borrowerService: BorrowerService) {
        this.borrowerService.borrowerChanged.subscribe(borrower => {this.borrower = borrower});
    }
}

borrower.service.ts

@Injectable()
export class BorrowerService {
    public borrowerChanged: Subject<Borrower> = new Subject<Borrower>();

    //event handler
    selectBorrower(borrower: Borrower) {
        this.borrowerChanged.next(borrower);
    }
}

考虑以下几点:

borrower.service.ts

import {Injectable} from '@angular/core';
import {BehaviorSubject} from 'rxjs';


@Injectable()
export class BorrowerService {

  public borrowerChanged = new BehaviorSubject<string>('Defaut Value');
  borrowerChangedObservable = this.borrowerChanged.asObservable();
  constructor(){}

  changeValue(value: string): void {
    this.borrowerChanged.next(value);
  }
}

然后在您的组件中:

借款人-report.component.ts

获得你做的值:

constructor(private borrowerService: BorrowerService) {
    this.borrowerService.borrowerChangedObservable
       .subscribe((borrower) => {
              console.log(borrower);
          });
    }

要设置新值,您需要执行以下操作:

sendNewValueToBorrowerService(){
this.borrowerService.changeValue('my new value');
}

并且不要忘记在同一模块的提供数组中添加服务,在声明数组中添加组件。

问题在于您的服务范围,@ngModule 未提供服务。如果您希望这是一个单例服务(多个组件的相同服务实例),那么您将希望在包含所有子组件的父模块中提供该服务。对于有保证的路线,请将此添加到您的 app.module.ts。在模块中导入它,并像在组件中一样将其作为服务提供(尽管将其作为提供者从组件中删除......您只希望父模块提供它)。

然后您可以将服务导入您已有的组件,provider 将成为父模块。基本思想是父模块将为所有子组件托管服务,因此所有子组件将接收相同的服务实例(因此具有相同的值)。

旁注: 提供了有关创建单例服务调用的详细信息 ApiService,应该可以作为可靠的指南。另一个最佳答案也提供了可靠的解释。

第二个注意事项:如果您希望从您的主题推送更新,您还需要使用 BehaviorSubject。对 BehaviorSubject 的订阅会自动更新,而对 Subjects 的订阅则必须手动调用。