首页 > 解决方案 > 角度注入组件到另一个布局组件

问题描述

我正在尝试将一个组件注入另一个布局组件?我正在尝试通过服务来做到这一点,但没有任何效果。

我的布局是:

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

我正在尝试将HelloWorldComponentDashboardComponent注入SecondarySidebarComponent

应用程序布局.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 -->

仪表板.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);
  }

}

辅助边栏.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);
  }

}

我哪里错了??

谢谢你。

标签: angular

解决方案


这一行:@ViewChild('secondarysidebar') secondarysidebar;insecondary-sidebar.service.ts似乎很可疑,因为服务通常没有 html 模板,因此不能有 viewchildren。我假设您要从中加载模板的viewchild app-layout.component.html

为了能够做到这一点,您需要创建一个您的继承SecondarySidebarService指令。dashboard.component.ts(但是你不能将它注入到你的侧边栏组件中来呈现内容。)

最好的解决方案可能是在您的 dom 的不同分支中创建一个 Viewportal ( https://material.angular.io/cdk/portal/overview ),SecondarySidebarComponent以便在您的 dom 中呈现组件SecondarySidebarComponent.

我为您创建了一个 stackblitz,它为您的用例演示了一个简单的实现。 https://stackblitz.com/github/Narmor/angular-view-portal

在示例中,aa 标签内的任何内容都app-sidebar-header-portal将在侧边栏组件中呈现。无论它在应用程序内部的什么地方使用。

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

建议为通过门户在应用程序的其他位置呈现的内容创建组件,因为否则样式封装会阻止您对内容进行样式设置。(如果您创建一个组件,整个组件将在门户中呈现,这会导致应用组件的样式。)


推荐阅读