【问题标题】:Angular - project content to another componentAngular - 项目内容到另一个组件
【发布时间】:2021-02-11 08:11:13
【问题描述】:

Angular 有没有办法将一个组件中的内容投射到另一个组件的“容器”中?不是从父级到子级,这可以通过 ng-content 完成,而是从一个组件到其表亲(通过父级)。

在我们的应用程序中,我们在应用程序组件中有布局,将页面分为 3 个元素:侧边菜单、静态标题和主内容面板。

在内容面板中,我们有路由器插座,它呈现智能组件的内容。例如,我们希望将其中一些内容投影到标题中。

以下是应用程序结构的非常简化的示例。困难在于不同的页面需要投射截然不同的内容,因此无法由一个数据驱动的组件轻松完成。

我们希望避免在标题中有条件地引用一堆智能组件,并根据主面板中当前加载的页面显示。

<app>
  <side-menu>...</side-menu>  <-- menu component
  <header>                    <-- header component
      <section>Static header content</section>
      <section>  ## Project content here ##  </section>
  </header>
  <main>
       <router-outlet></router-outlet>   <-- page components
  </main>
</app>

我们尝试查看模板出口,但我们无法将一个组件中定义的模板连接到另一个组件中的出口。

【问题讨论】:

    标签: angular


    【解决方案1】:

    您可以使用其中包含 templateRef 的 behaviorSubject 的服务。

    import { Injectable, TemplateRef } from "@angular/core";
    import { BehaviorSubject } from "rxjs";
    
    @Injectable()
    export class TemplateService {
      sharedTemplateSubject: BehaviorSubject<
        TemplateRef<any>> = new BehaviorSubject<TemplateRef<any>>(null);
      sharedTemplate$ = this.sharedTemplateSubject.asObservable();
      constructor() {}
    }
    

    现在你需要做的就是订阅这个服务器的 sharedTemplate$ 变量,当它发出这个模板时,使用 viewContainerRef 和 createEmbededView 渲染这个模板。

    export class AppComponent implements OnInit {
      @ViewChild("container", { read: ViewContainerRef })
      container: ViewContainerRef;
      constructor(private templateService: TemplateService) {}
    
      ngOnInit() {
        this.templateService.sharedTemplate$.subscribe(template => {
          this.container.createEmbeddedView(template);
        });
      }
    }
    

    【讨论】:

      【解决方案2】:

      如果我正确理解了这个问题,我建议使用Service

      import { Injectable } from '@angular/core';
      
      @Injectable()
      export class CustomService{
      
        sharedContent: string = 'test';
      
      }
      

      从这里你可以从你的任何组件中设置/获取这个字符串。

      import { Component, OnInit } from '@angular/core';
      import { CustomService } from './services/custom-service.service';
      
      @Component({
        selector: 'app-home',
        templateUrl: './home.component.html',
        styleUrls: ['./home.component.scss'],
      })
      
      export class HomeComponent implements OnInit {
      
        sharedContent: string;
      
        constructor(private customService: CustomService) {
          this.sharedContent = this.customService.sharedContent;
        }
      
        changeContent(): void {
          this.customService.sharedContent = 'new test';
        }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 2016-11-04
        • 2015-04-05
        • 1970-01-01
        • 1970-01-01
        • 2018-06-28
        • 1970-01-01
        相关资源
        最近更新 更多