用于重写nz-drawer样式的dark-drawer组件定义:
dark-drawer.component.html:
<nz-drawer nzWrapClassName="darkdrawer" [nzTitle]="nzTitle" [nzPlacement]="nzPlacement" [nzClosable]="nzClosable"
[nzMaskClosable]="nzMaskClosable" [nzWidth]="nzWidth" [nzVisible]="nzVisible" [nzMask]="false"
[nzCloseIcon]="closeTpl" (nzOnClose)="onClose($event)">
<ng-container *ngIf="!(templateContent || componentContent)">
<ng-content></ng-content>
</ng-container>
<ng-container *ngIf="templateContent">
<ng-container [ngTemplateOutlet]="templateContent"></ng-container>
</ng-container>
<ng-container *ngIf="componentContent">
<ng-container *ngComponentOutlet="componentContent"></ng-container>
</ng-container>
</nz-drawer>
<ng-template #closeTpl>
<span class="close-icon" nz-icon nzType="close" nzTheme="outline"></span>
</ng-template>
dark-drawer.component.scss:
::ng-deep .darkdrawer {
.ant-drawer-content {
background-color: transparent;
}
.ant-drawer-header {
background-color: #07183de3;
border-bottom: 1px solid #3268D0;
height: 48px;
}
.ant-drawer-title {
color: rgba(255, 255, 255, 0.90);
line-height: 16px;
}
.ant-drawer-body {
padding: 10px 10px 10px 20px;
background-color: rgb(10 17 24 / 84%);
}
.ant-drawer-close {
height: 48px !important;
padding: 0px !important;
margin-right: 20px !important;
}
}
::ng-deep .ant-drawer.no-mask {
width: 0px !important;
}
.close-icon {
color: rgba(255, 255, 255, 0.8);
&:hover {
color: #ffffff;
}
}
dark-drawer.component.ts:
import { Component, EventEmitter, Input, OnInit, Output, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewChildren } from '@angular/core';
@Component({
selector: 'dark-drawer',
templateUrl: './dark-drawer.component.html',
styleUrls: ['./dark-drawer.component.scss']
})
export class DarkDrawerComponent implements OnInit {
@Input() nzTitle: string = "提示";
@Input() nzPlacement: 'left' | 'right' = 'left';
@Input() nzClosable: boolean = true;
@Input() nzMaskClosable: boolean = true;
@Input() nzWidth: number = 460;
@Input() nzVisible: boolean = true;
nzContentParams: object;
templateContent: TemplateRef<any>;
componentContent: Type<any>;
@Output() nzClose = new EventEmitter<any>();
constructor(
) {
}
ngOnInit(): void {
}
set nzContent(content: TemplateRef<any> | Type<any>) {
if (content instanceof TemplateRef) {
this.templateContent = content as TemplateRef<any>;
} else {
this.componentContent = content as Type<any>;
}
}
onClose(evt) {
this.nzClose.emit(evt);
}
}
在其他组件中可以使用它:
<dark-drawer nzTitle="提示" nzPlacement="left" [nzWidth]="460" [nzVisible]="panelVisiable"
(nzClose)="closePanel($event)">
<my-component></my-component>
</dark-drawer>
想要和ant design提供的nzDrawerService一样动态生成drawer组件,封装自己的service服务。
dark-drawer.service.ts:
import { Overlay, } from '@angular/cdk/overlay';
import { ComponentPortal, DomPortalHost, PortalInjector } from '@angular/cdk/portal';
import { NzDrawerService } from 'ng-zorro-antd/drawer';
import { DarkDrawerComponent } from './dark-drawer.component';
import { ComponentRef, EventEmitter, Injectable, TemplateRef, Type } from '@angular/core';
interface DARWER_PARAMS {
that: object;
nzTitle?: string;
nzPlacement?: 'left' | 'right';
nzContent?: TemplateRef<any> | Type<any>;
nzClosable?: boolean;
nzMaskClosable?: boolean;
nzWidth?: number;
nzVisible?: boolean;
nzContentParams?: object;
nzOnCancel?: Function;
}
@Injectable({
providedIn: 'root',
})
export class DarkDrawerService {
constructor(
private drawService: NzDrawerService,
private overlay: Overlay
) {
}
create(params: DARWER_PARAMS) {
// 创建Overlay实例,overlay实例上就是一个PortalOutlet
const overlayRef = this.overlay.create();
const compPortal = new ComponentPortal(DarkDrawerComponent, null, null); // 创建portal
const comptRef: ComponentRef<DarkDrawerComponent> = overlayRef.attach(compPortal); // 将portal挂载到Ovelay实例上
const compInstance = comptRef.instance;
compInstance.nzTitle = params.nzTitle;
compInstance.nzPlacement = params.nzPlacement;
compInstance.nzContent = params.nzContent;
compInstance.nzContentParams = params.nzContentParams;
compInstance.nzClosable = params.nzClosable;
compInstance.nzWidth = params.nzWidth;
compInstance.nzMaskClosable = params.nzMaskClosable;
compInstance.nzVisible = params.nzVisible != undefined ? params.nzVisible : true;
// 处理返回回来的事件
compInstance.nzClose.subscribe(evt => {
if (params.nzOnCancel) {
const _this = params.that;
params.nzOnCancel.call(_this, evt);
comptRef.destroy();
overlayRef.detach();
}
})
}
}
使用DarkDrawerService时和nzDrawerService服务相当接近:
this.drawerService.create({
that: this,
nzTitle: '提示',
nzContent: MyComponent,
nzPlacement: 'left',
nzClosable: true,
nzMaskClosable: true,
nzWidth: 460,
nzOnCancel: () => {
this.panelVisiable= false;
}
});
参考:
https://juejin.cn/post/7101595622850969614
https://segmentfault.com/a/1190000039688460
https://segmentfault.com/a/1190000039791884