通过服务进行的通信无法正常工作Angular 8

时间:2019-07-11 21:02:17

标签: angular rxjs6

我正在做一个项目,父母和孩子需要通过服务进行沟通。按照官方文档中的this article,我无法使其正常工作。

这是我创建的服务:

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

@Injectable()
export class CommonService {
    private _propertyChangeAnnouncedSource = new Subject<string>();
    propertyChangeAnnounced$ = this._propertyChangeAnnouncedSource.asObservable();

    public announcePropertyChange(data: string) {
        this._propertyChangeAnnouncedSource.next(data);
    }
}

在父组件中,我需要导入的所有内容:

@Component({
    selector: 'app-parent',
    templateUrl: './parent.component.html',
    styleUrls: ['./parent.component.scss'],
    providers: [CommonService]
})
export class ParentComponent implements OnInit {

    constructor(private _commonService: CommonService) {

    }

    tellChild(data): void {
        this._commonService.announcePropertyChange(data);
    }

}

这是孩子的代码:

@Component({
    selector: 'app-child',
    templateUrl: './child.component.html',
    styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit, OnDestroy {
    private subscription: Subscription;

    constructor(private _commonService: CommonService) {
        this.subscription = this._commonService.propertyChangeAnnounced$.subscribe(
            data => {
                console.log(data);
          });
    }
}

当我调用announcePropertyChange时,孩子没有响应。有什么建议吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

可能有几个问题:

  1. 检查子组件和父组件是否具有相同的服务实例。您可能已经为CommonService提供了多个位置,因此父级和子级可能不会共享该类的同一实例。

  2. 您如何准确执行tellChild()方法?也许您在父组件启动时执行了该方法,因此Observable发出了新事件,但是子事件尚未创建并且尚未订阅Observable,它将跳过该事件。

可能的解决方案:

  • 如果您遇到问题2,则建议您更新CommonService以使用BehaviorSubject而不是Subject。 private _propertyChangeAnnouncedSource = new BehaviorSubject<string>(null);这样,无论何时有人订阅Observable,他们都将获得最新价值并继续监视进一步的变化。如果您想避免由于BehaviorSubject引起的初始null值,建议您像这样修改Observable:propertyChangeAnnounced$ = this._propertyChangeAnnouncedSource.asObservable() .pipe(filter(x => x !== null));

现在就这样,让您听听这2个消息,如果仍有问题,我将在稍后更新我的回复。

答案 1 :(得分:0)

您的子组件constructor中似乎有一个错字

private subscription;
  constructor(private _commonService: CommonService) {
        this.subscription = this._commonService.propertyChangeAnnounced$.subscribe(
            data => {
                console.log(data,'from child');
          });
    }

这对我有用。另外,请显示如何在代码中调用tellChild

<button (click)="tellChild('TestData')">Tell child</button>

检查working Demo Here: