Angular динамически добавлять компонент к другому компоненту - PullRequest
0 голосов
/ 03 мая 2020

Для меня это супер базовая c функциональность, которую должна иметь среда FrontEnd.
Но я не смог найти ее в Angular.

У меня есть такой сценарий:
Один компонент выполняет некоторый запрос к внешней службе с асинхронным вызовом (в данном примере это поддельный вызов), затем на основе ответа (если число нечетное или четное ) этот компонент добавляет к этому представлению один или другой компонент.

Рассмотрите этот небольшой пример

import { Component, OnInit } from '@angular/core';
import { of, merge, Observable } from 'rxjs';
import { mapTo, delay } from 'rxjs/operators';

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

  constructor() { }

  ngOnInit() {
  const subscribe = this.serverFakeCall().subscribe(
    val => {
      console.log("received value ", val);
      if (val%2 == 0) {
        // The OddComponent should be displayed
      } else {
        // The EvenComponent should be displayed
      }
    });
  }

  private serverFakeCall() : Observable<number>{
    const randomNumber = Math.floor((Math.random() * 2))
    return of(randomNumber).pipe(delay(3000))
  }

}

Полный пример кода доступен здесь https://stackblitz.com/edit/angular-7dtg8w

Я хочу добавить динамически OddComponent или EvenComponent Я не хочу добавлять их обоих в шаблон и затем «скрывать» ту или иную с помощью ngIf

Как лучше всего достичь этого результата?

1 Ответ

0 голосов
/ 03 мая 2020

Это было невозможно до Angular v9.

Теперь, благодаря Ivy (преемнику View Engine), введено понятие locality , и оно становится ленивым загружать компоненты, то есть вы можете динамически загружать компоненты во время выполнения.

Есть замечательная статья от Natanel Basal , объясняющая, как это реализовать. Один фрагмент из статьи:

import { FooComponent } from './foo/foo.component';

@Component({
  template: `
    <button (click)="loadFoo()">Load FooComponent</button>
    <ng-container *ngIf="foo">
       <ng-template [ngComponentOutlet]="foo | async"></ng-template>
    </ng-container>
  `
})
export class AppComponent {
  foo: Promise<Type<FooComponent>>;

  loadFoo() {
    if (!this.foo) {
      this.foo = import(`./foo/foo.component`)
                       .then(({ FooComponent }) => FooComponent);
    }
  }
}

Я бы предложил прочитать всю статью, чтобы узнать все подробности об этом.

...