gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 20:15:22 25 4
gpt4 key购买 nike

我正在尝试根据某些操作(例如按钮单击)从不同的路由组件中加载 mat-sidenav 中的不同组件?

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

我还在 mat-sidenav 中创建了一个 ng-container 并将其 ViewConteinerRef 存储在 SidenavService 中,现在在组件层次结构中的任何组件中,我可以注入(inject) SidenavService 并且可以使用 ViewConteinerRef 来创建嵌入式 View 。

堆栈闪电链接
https://stackblitz.com/edit/angular-material-sidenav-dynamic-content

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

最佳答案

尝试使用您的 StackBlitz,我想出了一个使用 portal component 的解决方案来自 Angular CDK(组件 DevKit)。

我所做的是修改原来的SidenavService允许 Portal 的代码传递给 Subject 这将发出 Portal订阅 Subject 的任何组件.然后,动态 sidenav 将具有 <ng-template>带有 cdkPortalOutlet 的sidenav内部的部分绑定(bind)到 Portal 的属性Subject :

<mat-sidenav #rightPanel position="end">
<ng-template [cdkPortalOutlet]="panelService.panelPortal | async"></ng-template>
</mat-sidenav>

export class AppComponent {
constructor(public panelService: PanelService) { }
}

但是,请务必导入 PortalModule来自 @angular/cdk/portal应用程序模块的入口点:

import { PortalModule } from '@angular/cdk/portal';
// ...

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

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

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

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

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供你玩耍。

希望这可以帮助!

关于angular - 从任何组件动态更改 mat-sidenav 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56772447/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com