Angular дочерний компонент не инициализируется, когда parent является функцией во время родительского oninit - PullRequest
0 голосов
/ 08 февраля 2020

У меня возникла проблема с отображением моего предупреждения при срабатывании в ResetPasswordComponent oninit. Блок подписки для AlertService не запускается, однако, если я перенесу код из oninit в конструктор, он будет работать. Однако, похоже, что не рекомендуется помещать код инициализации / объявления в конструктор. Так есть ли лучшее решение для этого?

Родитель

export class ResetPasswordComponent implements OnInit {
  public email: string;
  public token: string;

  constructor(public alertService: AlertService) {
  }

  ngOnInit() {
    this.token = this.route.snapshot.queryParamMap.get('token');
    this.email = this.route.snapshot.queryParamMap.get('email');
    console.log("Parent on init");
    if (this.token === null || this.token === "" ||
        this.email === null || this.email === "") {
      this.form.disable();
      this.alertService.error("Invalid link");
    }
  }
}

Ребенок

export class AlertComponent implements OnInit, OnDestroy {
  private subscription: Subscription;
  public messages: string[];
  public type: string;

  constructor(private alertService: AlertService) {

  }

  ngOnInit() {
    console.log(this.alertService.getAlert());
    this.subscription = this.alertService.getAlert().subscribe(data => {
      console.log("OK");
      // do something
    });
    console.log("Child On init");
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

AlertService

@Injectable({ providedIn: 'root' })
export class AlertService {
  private subject = new Subject<Alert>();

  constructor(private router: Router) { }

  error(message: any, navigateTo = null) {
    if (navigateTo !== null) {
      this.navigateWithMessage(navigateTo, AlertType.error, message);
    }
    const alert: Alert = { type: AlertType.error, message };
    this.subject.next(alert);
    console.log("NEXT");
  }

  getAlert(): Observable<Alert> {
    return this.subject.asObservable();

}

1 Ответ

0 голосов
/ 08 февраля 2020

Я считаю, что проблема в том, что событие запускается до того, как дочерний компонент начал подписку в ngOnInit. Когда дочерний компонент наконец подписывается, событие «Неверная ссылка» уже произошло и завершено.

Для этого есть пара решений: одно меняет ваш предмет на BehaviorSubject, например:

private subject = new BehaviorSubject<Alert>(null);

Теперь, как только ребенок подписывается, он получит последнее событие от Observable, даже после того, как событие произошло.

Другим решением может быть добавление оператора shareReplay () к вашей наблюдаемой. Но в этом конкретном случае c, когда вы уже используете предметы, я бы go предложил бы решение BehaviorSubject.

...