Angular - жизненный цикл: дочерний компонент должен быть полностью загружен - PullRequest
4 голосов
/ 28 мая 2019

Возможно ли уведомление родительского компонента о загрузке дочернего компонента, особенно когда речь идет о ng-container и ng-template.
Как и в Yes! I see that you've grown strong, my child!

Скажем, у нас есть такой компонент:

@Component({
  selector: 'my-app',
  template: `
  <ng-container *ngIf="!showElse; else elseBlock">
    <h1>Hi!</h1>
  </ng-container>
  <ng-template #elseBlock>
    <hello name="{{ name }}"></hello>
  </ng-template>
  <button (click)="showElse = !showElse">Show else</button>
  `,
  styles: ['']
})
export class AppComponent  {
  name = 'Angular';
  showElse = false;
  @ViewChild('hello') hello: HelloComponent;
}

Есть ли способ для AppComponent узнать, полностью ли загружен HelloComponent или мне нужно специальное решение внутри HelloComponent?

В настоящее время я сижу с менее чем оптимальным решением (материал на основе setTimeout(), который мне не нравится).
Вот о чем я думаю:
- Добавить EventEmitter к моему HelloComponent;
- Используйте жизненный цикл HelloComponent для создания события, скажем, ngAfterContentChecked
- Перехватите это событие в моем AppComponent и сделайте это.

Что вы думаете по этому поводу?


Редактировать

Пока что я попробовал то, что вы предложили (подключитесь к AfterViewInit, используйте @ViewChildren ...), но безуспешно.
Просто чтобы быть уверенным, я попробовал снова без <ng-container>...<ng-template> и просто скрыл свой HelloComponent, используя директиву [hidden] ...

Выдав событие во время HelloComponent AfterContentChecked и перехватив это событие в AppComponent, оно работает как заклинание. (см. на стеке )
Это решение более стильное, чем мое предыдущее setTimeout

Теперь я решил использовать механику <ng-container>...<ng-template>, потому что мой фактический компонент всего на 1056 * крошечный бит тяжелее, чем пример HelloComponent.
Если у кого-то есть лучшая идея продолжать использовать механику контейнера-шаблона, я весь в ушах.

Ответы [ 3 ]

1 голос
/ 28 мая 2019

Как вы и предлагали, используйте EventEmitter в хуке жизненного цикла AfterContentChecked () для отправки события вашему родительскому компоненту. Это просто и правильно использует API жизненного цикла Angular. https://angular.io/guide/lifecycle-hooks#lifecycle-sequence

0 голосов
/ 28 мая 2019

вы можете использовать ngAfterVIewChecked в родительском компоненте, который сообщает родительскому компоненту, что angular завершил обнаружение изменений на всех дочерних элементах

Таким образом, если у вас есть 5 дочерних компонентов, вы можете знать, когда обновлены все дочерние представления, но вы не можете знать, был ли обновлен определенный дочерний компонент

0 голосов
/ 28 мая 2019

Вы можете присоединиться к AfterViewInit, но это не всегда так, учитывая, что у вас есть *ngIf на вашем дочернем компоненте, тогда вам нужно сделать это.

private helloPlaceholder: ElementRef;

 @ViewChild('hello') set hello(content: HelloComponent) {
    this.helloPlaceholder = content;
    // you can check and do your stuff here
 }
...