Как заменить контейнер на комплектующие? - PullRequest
0 голосов
/ 07 марта 2020

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

Теперь в любое место приложения я отправляю команду, используя Subject() с данными:

{data: {}, type: "showSearch"} 
{data: {}, type: "showResultSearch"}
{data: {}, type: "showUserBlock"} 
{data: {}, type: "showContacts"}  

Затем в SideBarComponent Я слушаю эти данные и применяю к различимому типу:

this.events.listen().subject((data) => {
     this.type = data.type;
);

Тогда внутри шаблона SideBarComponent Я делаю:

<app-search *ngIf="type === 'showSearch'"></app-search>
<app-result-search *ngIf="type === 'showResultSearch'"></app-result-search>
<app-user-block *ngIf="type === 'showUserBlock'"></app-user-block>
<app-contracts *ngIf="type === 'showContacts'"></app-contacts>

Итак, как решить эту проблему более изящно? Теперь у меня более 10 компонентов.

Ответы [ 2 ]

0 голосов
/ 08 марта 2020

Вместо *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

0 голосов
/ 07 марта 2020

Думаю, я бы порекомендовал вам использовать маршрутизатор и его функции, я бы сказал, что эти компоненты должны отображаться по URL вашего приложения.

url будет представлять, к какому ресурсу вы обращаетесь egz:

my-app/search

my-app/contacts

https://angular.io/guide/router

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...