首页 > 解决方案 > 材质侧导航右侧菜单中组件提供的动态内容

问题描述

我已经在一个模板中实现了一个右手菜单覆盖,该模板已经使用 Materials sidenavs 使用了左手导航。我需要一个额外的 sidenav 来编辑从右侧滑入的内容。这是在 app.component 中声明的,我添加了一个服务,它允许我通过通知 app.component 切换 sidenav 的状态来从任何组件打开右侧 sidenav。这是它在 app.component 中的布局方式:

 <mat-sidenav-container>


  <mat-sidenav #appDrawer mode="{{ mode }}" opened="{{ opened }}"
    disableClose={{disableClose}} position="start" 
    (openedChange)="navStateChangeEmit($event)">

    left navigation menu content

  </mat-sidenav>


  <!-- Right Hand overlay menu -->
  <mat-sidenav  #appDrawerRH mode="over" opened="{{openedRmenu}}"
  position="end" (openedChange)="r_navStateChangeEmit($event)">

  Right Menu content here

  </mat-sidenav>

  <mat-sidenav-content class="main-content">
  </mat-sidenav-content>
</mat-sidenav-container>

我需要的是右手侧导航是多用途的,并且打开它的组件决定在其中显示什么内容/表单。我不确定如何构建它。

标签: angularangular-material

解决方案


好吧,我已经整理了一个关于 Stackblitz 的示例,执行我在下面所说的操作。

1 - 构建一个服务来控制应该在右侧面板上显示的内容:

@Injectable({ providedIn: "root" })
export class SidenavRightPanelContentService {
  private _componentPortal$ = 
    new BehaviorSubject<ComponentPortal<any> | null>(null);

  getComponentPortal$() {return this._componentPortal$.asObservable();}

  setComponentPortal(component: ComponentType<any>) {
    this._componentPortal$.next(new ComponentPortal<any>(component));
  }
}

2 - 在该面板上准备一个门户出口以接收组件门户。

此外,在示例中,我放置了一些按钮来说明用法:

<mat-sidenav-container class="example-container">
    <mat-sidenav opened mode="side">Start content</mat-sidenav>
    <mat-sidenav #rightSideNav="matSidenav" mode="over" position="end">
        <div class="container">
            <ng-template [cdkPortalOutlet]="_rightSideComponentPortal$ | async"></ng-template>
        </div>
    </mat-sidenav>
    <button (click)="_loadComponent1()" mat-raised-button color="primary">Load Component 1</button>
    <button (click)="_loadComponent2()" mat-raised-button color="warn">Load Component 2</button>
</mat-sidenav-container>

3 - 准备 Sidenav 主机 typescript 类以显示所需的组件

测试组件 (AppComp1ComponentAppComp2Component) 是您希望在右侧导航面板上动态显示的组件。

private _rightSideNav: MatSidenav;
@ViewChild(MatSidenavContainer) _snc: MatSidenavContainer;

_rightSideComponentPortal$ = this._sn.getComponentPortal$().pipe(
  tap((_) => _ ? this._rightSideNav.open() : null),
);

constructor(public _sn: SidenavRightPanelContentService) {}

ngAfterViewInit() {this._rightSideNav = this._snc.end as MatSidenav;}

_loadComponent1() {this._sn.setComponentPortal(AppComp1Component);}

_loadComponent2() {this._sn.setComponentPortal(AppComp2Component);}

好吧,这只是在 sidenav 中显示组件的基本内容。SidenavRightPanelContentService只需在您想要设置要在右侧面板上显示的组件的任何位置注入。当然,您可能必须填补一些空白才能使其有用。这只是为了指出一些方向。


推荐阅读