组件订阅不会看到具有Subject Observable调用next()的Angular Service

时间:2017-10-06 19:42:01

标签: angular rxjs subject-observer

我想从Angular Service中检索更新的对象值(借用者)。我在服务中创建了一个RxJS Subject,这样多个组件就可以订阅它并获得更新的值。

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

如果我在BorrowerService类中订阅,我发现.next()按预期工作。似乎Subject是调用.next()的Service类和组件之间的不同实例,因此不会获得该订阅。

这是否无法理解Angular Services或Observables?如何在不知道何时致电.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);
    }
}

2 个答案:

答案 0 :(得分:7)

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

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

附注:This SO Answer提供有关创建单身人士服务电话ApiService的详细信息,并应作为可靠的指南。另一个最佳答案也提供了一个可靠的解释。

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

答案 1 :(得分:2)

请考虑以下事项:

<强> 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');
}

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