Вместо *ngIf
или даже блока ngSwitch
вы можете использовать объект и динамически визуализировать компоненты, например:
Angular <9 </strong>:
Модуль :
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { ContactsComponent } from './contacts.component.ts';
import { ResultSearchComponent } from './result-search.component.ts';
import { SearchComponent } from './search.component.ts';
import { UserBlockComponent } from './user-block.component.ts';
const ENTRY_COMPONENTS = [
ContactsComponent,
ResultSearchComponent,
SearchComponent,
UserBlockComponent,
];
const DECLARATIONS = [
...ENTRY_COMPONENTS,
AppComponent,
];
@NgModule({
bootstrap: [AppComponent],
declarations: DECLARATIONS,
imports: [BrowserModule],
entryComponents: ENTRY_COMPONENTS,
})
export class AppModule {}
Компонент :
import { Component, Type } from '@angular/core';
import { switchMap } from 'rxjs/operators';
import { ContactsComponent } from './contacts.component';
import { ResultSearchComponent } from './result-search.component';
import { SearchComponent } from './search.component';
import { UserBlockComponent } from './user-block.component';
const componentsMapper = {
showContacts: ContactsComponent,
showResultSearch: ResultSearchComponent,
showSearch: SearchComponent,
showUserBlock: UserBlockComponent,
// others
};
Angular 9 :
Модуль :
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
bootstrap: [AppComponent],
declarations: [AppComponent],
imports: [BrowserModule],
})
export class AppModule {}
Компонент :
import { Component, Type } from '@angular/core';
import { switchMap } from 'rxjs/operators';
const componentsMapper = {
showContacts: import('./contacts.component').then(({ ContactsComponent }) => ContactsComponent),
showResultSearch: import('./result-search.component').then(({ ResultSearchComponent }) => ResultSearchComponent),
showSearch: import('./search.component').then(({ SearchComponent }) => SearchComponent),
showUserBlock: import('./user-block.component').then(({ UserBlockComponent }) => UserBlockComponent),
// others
};
Общий код для любой Angular версии (9 вниз):
Шаблон :
<ng-template [ngComponentOutlet]="ngComponentOutlet$ | async"></ng-template>
Компонент :
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
readonly ngComponentOutlet$ = this.events.listen().pipe(
switchMap(data => this.loadComponent(data.type))
);
async loadComponent(type: string): Promise<Type<any>> {
return await componentsMapper[type];
}
}
Как вы, возможно, заметили, разница между двумя версиями заключается лишь в том, что в Angular 9 нет необходимости добавлять динамические c компоненты в entryComponents раздел в @NgModule
и даже не в декларациях . Код может быть импортирован действительно динамически, по запросу.
Angular <9 DEMO </strong>
Angular 9 DEMO
Подробнее:
https://medium.com/angular-in-depth/asynchronous-modules-and-components-in-angular-ivy-1c1d79d45bd3
https://medium.com/angular-in-depth/lazy-load-components-in-angular-596357ab05d8
https://netbasal.com/welcome-to-the-ivy-league-lazy-loading-components-in-angular-v9-e76f0ee2854a