Связь через сервис не работает Angular 8 - PullRequest
1 голос
/ 12 июля 2019

Я работаю над проектом, в котором родители и дети должны общаться через службу. После этой статьи в официальной документации я не могу заставить ее работать.

Это сервис, который я создал:

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 ]

1 голос
/ 12 июля 2019

Может быть несколько проблем:

  1. Проверьте, есть ли у дочернего и родительского компонента один и тот же экземпляр службы.Вы могли бы предоставить CommonService несколько мест, таким образом, родитель и потомок могут не использовать один и тот же экземпляр класса.

  2. Как вы точно выполняете метод tellChild()?Возможно, вы выполняете метод при инициации родительского компонента, поэтому Observable отправляет новое событие, но потомок еще не создан и не подписан на Observable, он пропускает событие.

Возможные решения:

  • Если проблема 2 относится к вашему случаю, тогда я предлагаю вам обновить CommonService, чтобы использовать BehaviorSubject вместо Subject.private _propertyChangeAnnouncedSource = new BehaviorSubject<string>(null); Таким образом, независимо от того, в какое время кто-то подписывается на Observable, он получит последнее значение и продолжит отслеживать дальнейшие изменения.Если вы хотите избежать начального значения null из-за BehaviorSubject, я предлагаю вам изменить Observable следующим образом: propertyChangeAnnounced$ = this._propertyChangeAnnouncedSource.asObservable() .pipe(filter(x => x !== null));

Пока это все, давайте послушаем вас об этих 2 и яобновлю мой ответ позже, если проблема не устранена.

0 голосов
/ 12 июля 2019

Похоже, в вашем дочернем компоненте опечатка 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>

Проверьте рабочую демонстрацию Здесь:

...