Инициализация компонента с помощью ngIf не вызывает ngOnInit - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть родительский компонент с некоторыми дочерними элементами, которые визуализируются на основе оценки ngIf.

Я на Angular 8.1.3

Родительский компонент

import { ActivatedRoute } from '@angular/router';
import {FirstStageViewComponent} from "src/app/first-stage-view/first-stage-view.component";
import {SecondStageViewComponent} from "src/app/second-stage-view/second-stage-view.component";
import {SecondStageFormComponent} from "src/app/second-stage-form/second-stage-form.component";
import {ThirdStageFormComponent} from "src/app/third-stage-form/third-stage-form.component";
import {ThirdStageViewComponent} from "src/app/third-stage-view/third-stage-view.component";
import { ProdService } from "src/app/service/prod-service";


@Component({
  selector: 'app-prod-view',
  templateUrl: './prod-view.component.html',
  styleUrls: ['./prod-view.component.css']
})
export class ProdViewComponent implements OnInit 
{

  id;
  _stage: string;
  constructor(private prodService: ProdService, private route: ActivatedRoute) { }

  ngOnInit() {

    this.route.params.subscribe(params => this.id=params.id);

    this.prodService.get(this.id).subscribe((data: string) => (this._stage = data["_stage"]),
                                           error => (console.log(error)));

  }

  talkBack(_updatedStage: string) {

    this._stage=_updatedStage;
  }

}

и его шаблон

<div class="container">


    <div *ngIf="_stage>0">
        <app-first-stage-view [id]=id></app-first-stage-view>
    </div>

    <div *ngIf="_stage==1 else stage2">
        <app-second-stage-form [id]=id (talk)=talkBack($event)></app-second-stage-form>
    </div>
    <ng-template #stage2>
    <div *ngIf="_stage>1">
        <app-second-stage-view [id]=id></app-second-stage-view>
    </div>
    </ng-template>


    <div *ngIf="_stage==2 else stage3">
        <app-third-stage-form [id]=id (talk)=talkBack($event)></app-third-stage-form>
    </div>
    <ng-template #stage3>
    <div *ngIf="_stage>2">
        <app-third-stage-view [id]=id></app-third-stage-view>
    </div>
    </ng-template>
</div>

Это второй дочерний компонент(тот, который не был правильно инициализирован)

import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormBuilder, FormArray, Validators } from "@angular/forms";
import { ThirdStageService } from "src/app/service/third-stage.service";

@Component( {
    selector: 'app-third-stage-form',
    templateUrl: './third-stage-form.component.html',
    styleUrls: ['./third-stage-form.component.css']
} )
export class ThirdStageFormComponent implements OnInit {

    tsForm: FormGroup;
    @Input() id: string;
    @Output() talk: EventEmitter<string> = new EventEmitter<string>();

    constructor( private tsService: ThirdStageService,
        private formBuilder: FormBuilder ) {}

    ngOnInit() {
        this.tsForm = this.formBuilder.group( {
            ingredient: "TEST"
        } );

    }

}

И сокращенный шаблон для тестирования

<div class="container">
    <form [formGroup]="tsForm" (ngSubmit)="onSubmit()">
        <div class="form-group">
            <label for="name">{{ tsForm.controls[0].value }}</label> <input type="text"
                class="form-control" id="ingredient" formControlName="ingredient"
                required>
        </div>
    </form>
</div>

Родитель получает значение _stage с сервера, и первый дочерний элемент получает правильно
Затем этот компонент возвращает новое значение _stage к своему родителю с помощью EventEmitter, и родитель соответствующим образом обновляет значение своей переменной.
Новое значение (2) фактически превращает мой второй ngIf вистина, и действительно, второй дочерний (он называется форма третьей ступени, не путайся) вызывается конструктор. Но его ngOnInit не запускается.
Значение по умолчанию "TEST" не отображается внутри моего поля ввода, и при проверке дерева компонентов через август я вижу, что две зависимости, введенные конструктором, присутствуют, в то время какFormgroup, созданная внутри ngOnInit, не является.
Если я создаю новый маршрут, указывающий непосредственно на мой дочерний компонент, все работает как положено.

1 Ответ

0 голосов
/ 30 сентября 2019

Хавьер, когда вы пишете

this.route.params.subscribe(params => this.id=params.id);
//here this.id has no value
this.prodService.get(this.id).subscribe(...)

Вам нужно использовать swithMap

this.route.params.pipe(
  switchMap((params)=>{ 
    //here you has "params" 
    this.id=params.id
    //we want return 
    return this.prodService.get(this.id)
  })
  ).subscribe((data: string) => (this._stage = data["_stage"]),
              error => (console.log(error))
  );
...