angular вставить компонент в другой компонент макета - PullRequest
0 голосов
/ 21 марта 2020

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

Мой макет:

AppComponent
       |
AppLayoutComponent
       |
------------------------------------------------------------
       |                             |                     |
SecondarySidebarComponent     DashboardComponent   RightSidebarComponent

Я пытаюсь внедрить HelloWorldComponent в SecondarySidebarComponent из DashboardComponent

app-layout.component. html

        <!-- Secondary sidebar-->
        <template #secondarysidebar></template>
        <!-- /secondary sidebar -->

        <!-- Main content -->
        <div class="content-wrapper">

            <!-- Page header -->
            <app-page-header></app-page-header>
            <!-- /page header -->

            <!-- Tabbar -->

            <!-- /tabbar -->

            <!-- Content area -->
            <div class="content">
                <router-outlet></router-outlet>
            </div>
            <!-- /content area -->

dashboard.component.ts

import { Component, OnInit, AfterContentInit, TemplateRef, ViewChild } from '@angular/core';
import { SecondarySidebarService } from '../shared/services/secondary-sidebar.service';
import { RightSidebarService } from '../shared/services/right-sidebar.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements AfterContentInit {
  @ViewChild(TemplateRef) secondarysidebar: TemplateRef<any>;

  constructor(private rightsidebar: RightSidebarService, private sidebar: SecondarySidebarService) { 

  }

  ngAfterContentInit() {
    this.sidebar.open(this.secondarysidebar);
  }

}

second-sidebar.service.ts

import { Injectable, ComponentFactoryResolver, Injector, Inject, TemplateRef, ApplicationRef, Type, ViewChild, ViewChildren, ViewContainerRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { SecondarySidebarComponent } from '../layouts/secondary-sidebar/secondary-sidebar.component';

export type Content<T> = string | TemplateRef<T> | Type<T>;

@Injectable({
  providedIn: 'root'
})
export class SecondarySidebarService {
  @ViewChild('secondarysidebar') secondarysidebar; 

  componentRef: any;

  constructor(private resolver: ComponentFactoryResolver,
    private injector: Injector,
    private appRef: ApplicationRef,
    @Inject(DOCUMENT) private document: Document,
  ) { }

  open<T>(content: Content<T>) {
    console.log('try to load component...');
      const factory = this.resolver.resolveComponentFactory(SecondarySidebarComponent);
      this.componentRef = this.secondarysidebar.createComponent(factory);
  }

}

Где я ошибаюсь ??

Спасибо.

1 Ответ

2 голосов
/ 22 марта 2020

Эта строка: @ViewChild('secondarysidebar') secondarysidebar; в secondary-sidebar.service.ts кажется подозрительной, потому что службы обычно не имеют html -темплат и поэтому не могут иметь viewchildren. Я предполагаю, что с viewchild вы хотите загрузить шаблон из app-layout.component.html?

Чтобы сделать это таким образом, вам нужно сделать вашу SecondarySidebarService директиву, от которой наследуется ваш dashboard.component.ts. (Но тогда вы не могли бы внедрить его в компонент боковой панели, чтобы отобразить содержимое.)

Лучшим решением для этого, вероятно, было бы создание Viewportal (https://material.angular.io/cdk/portal/overview) в ваш SecondarySidebarComponent так что любые компоненты, находящиеся в другой ветви вашего домена, могут отображать компоненты внутри вашего SecondarySidebarComponent.

Я создал для вас стек-блиц, который демонстрирует простую реализацию для вашего сценария использования. https://stackblitz.com/github/Narmor/angular-view-portal

В этом примере все, что находится внутри тега app-sidebar-header-portal, будет отображаться в компоненте боковой панели. Независимо от того, где он используется внутри приложения.

<app-sidebar-header-portal>
  Hello World!
</app-sidebar-header-portal>

Рекомендуется создавать компоненты для контента, который отображается в другом месте приложения через портал, потому что в противном случае инкапсуляция стиля не позволит вам стилизовать контент. (Если вы создаете компонент, весь компонент будет отображаться на портале, что приводит к стилям применяемого компонента.)

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