使用angular CDK包提供的Overlay封装ant design drawer组件

用于重写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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值