首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从任何组件动态更改mat-sidenav内容

从任何组件动态更改mat-sidenav内容
EN

Stack Overflow用户
提问于 2019-06-26 20:07:23
回答 1查看 3.2K关注 0票数 5

我正在尝试在mat-sidenav中加载不同的组件,这些组件来自不同的路由组件,基于某些操作,比如单击按钮?

我已经创建了一个单独的服务'SidenavService‘来使用@ViewChild获取对mat-sidenav的引用,这样我就可以控制(如打开、关闭、切换等)。应用程序中的任何位置都可以使用sidenav。

我还在mat-sidenav中创建了一个ng容器,并将其ViewConteinerRef存储在SidenavService中,现在在组件层次结构中的任何组件中,我可以注入SidenavService,我可以使用ViewConteinerRef创建嵌入式视图。

stackblitz链接https://stackblitz.com/edit/angular-material-sidenav-dynamic-content

有没有更好的方法来实现这一点?从应用程序的任何位置加载mat-sidenav中的不同组件。

EN

回答 1

Stack Overflow用户

发布于 2020-01-02 22:04:54

在试验您的StackBlitz时,我想出了一个使用Angular CDK (组件DevKit)中的portal component的解决方案。

我所做的是修改原始的SidenavService代码,以允许将Portal传递给Subject,该any将向订阅了该Portal的任何组件发出该Subject。然后,动态sidenav将在sidenav内拥有一个<ng-template>部分,并将cdkPortalOutlet属性绑定到Portal Subject

代码语言:javascript
复制
<mat-sidenav #rightPanel position="end">
  <ng-template [cdkPortalOutlet]="panelService.panelPortal | async"></ng-template>
</mat-sidenav>
代码语言:javascript
复制
export class AppComponent {
  constructor(public panelService: PanelService) { }
}

但是,请确保将PortalModule@angular/cdk/portal入口点导入到应用程序的模块中:

代码语言:javascript
复制
import { PortalModule } from '@angular/cdk/portal';
// ...

@NgModule({
  imports: [
    // ...
    PortalModule
  ],
  // ...
})

通过允许SidenavService代码允许Portal引用,您现在可以将模板引用(TemplateRef)或组件(ComponentType)传递给SidenavService。这允许简化代码,其中不需要为sidenav的动态内容创建专用组件。

但是,TemplatePortal (which is a Portal that represents an embedded template)要求为第二个参数指定ViewContainerRef。在这种情况下,我所做的是允许用户指定要传递给将用于TemplatePortal的服务的ViewContainerRef

无论如何,这是服务代码的一部分。(注意:我已经将服务名称修改为一个听起来更好的名称:PanelService)

代码语言:javascript
复制
import { from } from 'rxjs';
// ...

export class PanelService {
  /** The panel. */
  panel: MatSidenav;
  private vcr: ViewContainerRef;
  // Note: The Portal class requires that a generic is specified for the component/template type.
  private panelPortal$ = new Subject<Portal<any>>();

  get panelPortal() {
    return from(this.panelPortal$); // Or this.panelPortal$.asObservable()
  }

  setViewContainerRef(vcr: ViewContainerRef) {
    this.vcr = vcr;
  }

  setPanelPortal(portal: Portal<any>) {
    this.panelPortal$.next(portal);
  }

  // Wrapper methods for MatSidenav go here.
  // ...
}

这里有一个StackBlitz供您试用。

希望这能有所帮助!

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56772447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档