angular6 填坑之sdk的方法

技术背景:angular + ant zorro

最为大型前端团队首选的前端技术框架,angular,在国内多少还是有些水土不服。本人将针对angular做个一系列的填坑分享。

坑一:sdk

angular的sdk不属于各个模块,直接挂载在body下面, ant design直接使用sdk,导致任何的弹出层,如select,dropdown,picker等在弹出来的时候自动创建覆盖全局的sdk,需要点击sdk才能关闭已打开的下拉。

明显需要点击两次才能出现一个下拉是产品们不能接受的。

解决方案有两个,一个是修改底层源码,抛弃sdk,明显成本巨大,而且bug会层出不穷,考虑不周全,建议缺少前端架构组的团队就不用考虑了。

本人选择了另外一个方案,有点取巧,但是能快速解决问题。

步奏一:

将sdk缩小至1x1px,让鼠标可以点击网页中任意地方。

.cdk-overlay-backdrop {

  width: 1px!important;

  height: 1px!important;

}

步奏二:监听document点击事件

document.addEventListener('click', (e) => {
  this.prepareHideModal(e);

});

步奏三:获取当前点击的select等的唯一标识

使用sdk的组件比较多,有的有唯一标识,没有的特殊处理

getSign(e) {

    for (const v of e['path']) {

      if (v.tagName == 'NZ-SELECT' || v.tagName == 'APP-SUBJECTPICKER') {

        // 下拉框获取sign

        if (v.classList[0].includes('ng-tns-')) {

          this.sign = v.classList[0];

        } else {

          this.sign = v.classList[1];

        }

        this.signType = 'NZ-NORMAL';

        break;

      } else if (v.tagName == 'NZ-PICKER') {

        // picker 获取sign

        this.sign = v.classList[0];

        this.signType = 'NZ-PICKER';

        break;

      }

      // popover 获取sign

      if (v.getAttributeNode && v.getAttributeNode('nz-popover') && v.getAttribute('nz-popover') == '') {

        this.sign = 'NZ-POPOVER';

        this.signType = 'NZ-POPOVER';

        break;

      }

    }

  }

步奏四:关闭已打开的下拉组件

为什么叫prepareHideModal,这是获取sign前的操作,先关闭再去获取点击下拉的sign

getSign方法在关闭后执行

prepareHideModal(e) {

    let doClose = true;

    if (window['globalSignType']) {

      this.hideAllmodal();

      window['globalSignType'] = null;

      return;

    }

    // 如果有sign,关闭已打开的

    if (this.sign) {

      let _sign = this.sign;

      // 判断某些情况下不关闭弹框

      if (_sign == 'NZ-POPOVER') {

        // 解决没有特使标识时点击cdk本身不消失

        for (const v of e['path']) {

          if (v.classList && v.classList.contains('cdk-overlay-container')) {

            doClose = false;

          }

        }

      } else {

        // 常规有指定sign时点击选择器自身时不消失

        for (const v of e['path']) {

          if (v.classList && v.classList.contains(_sign)) {

            doClose = false;

            break;

          }

        }

      }

      doClose && this.hideModal(_sign);

    }

    this.getSign(e);

  }

步奏五:最重要的关闭sdk,这边采用了最简单的,模拟sdk点击,完全使用sdk自己的方法

hideModal(sign) {

    let cdkDom = document.querySelectorAll('.cdk-overlay-backdrop.cdk-overlay-dark-backdrop.cdk-overlay-backdrop-showing');

    let domLen = cdkDom.length;

    // 循环cdk,找到它自身的cdk,模拟点击隐藏

    for (var i = 0; i < domLen; i++) {

      var v = cdkDom[i];

      if (v['style'].display != 'none') {

        v['click']();

        break;

      }

    }

    this.sign = null;

    this.signType = null;

  }

至此算是解决了使用skd组件需要点击两次的坑,但是会引起另外一个坑,当页面出现滚动条时,已打开的下来组件位置不会跟着滚动而去改变。这边会在另外一篇博客中解决

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Angularjs material 实现搜索框功能

    angular-material 是 AngularJS 的一个子项目,用来提供实现了 Material Design 风格的组件. Material 提供了大量的android 风格的UI组件,使用 angularjs + Material 可以很容易开发出风格接近原生 Android 5.x 的web界面.但在实际使用的过程中并不总是能满足我们的需求.开发一个组件就成了我们必须学习的内容. 下面是一个组件的实现: //前面省略若干代码 directive('mdSearchInput',[f

  • Angular(5.2->6.1)升级小结

    在前面的文章中也曾经分别提到过,angular6由于存在一些稍大的变化,所以不能像Angular4到Angular5那样基本无感地进行升级,这里结合官方提示,简单整理一下Angular5.2到目前稳定的6.1的升级要点. 事前准备 变更内容 除此之外,还需要确认如下内容: tsconfig.json: preserveWhitespaces设定为off(v6缺省设定) package.json中scripts的使用,所有的cli命令统一使用两个横线–传入参数(POSIX规范) ngModelCh

  • Angular使用Restful的增删改

    这篇来看一下如何进行增删改. 删除 使用delete进行删除,一般页面设计的时候也基本都是在列表页进行操作的.首先为删除的链接添加一个函数,因为一般删除都需要传入可定位删除的id或者name,前提是后端api是否支持,查看如下的调用之后,可以看到: 所以,只需要method使用delete,在传入的url中指定id或者name即可. 删除的restful调用:https://docs.konghq.com/0.13.x/admin-api/#delete-api 模版修改 html页面做如下修改

  • 详解angular2封装material2对话框组件

    1. 说明 angular-material2自身文档不详,控件不齐,使用上造成了很大的障碍.这里提供一个方案用于封装我们最常用的alert和confirm组件. 2. 官方使用方法之alert ①编写alert内容组件 @Component({ template : `<p>你好</p>` }) export class AlertComponent { constructor(){ } } ②在所属模块上声明 //必须声明两处 declarations: [ AlertComp

  • 从源码看angular/material2 中 dialog模块的实现方法

    本文将探讨material2中popup弹窗即其Dialog模块的实现. 使用方法 引入弹窗模块 自己准备作为模板的弹窗内容组件 在需要使用的组件内注入 MatDialog 服务 调用 open 方法创建弹窗,并支持传入配置.数据,以及对关闭事件的订阅 深入源码 进入material2的源码,先从 MatDialog 的代码入手,找到这个 open 方法: open<T>( componentOrTemplateRef: ComponentType<T> | TemplateRef

  • Material(包括Material Icon)在Angular2中的使用详解

    1.引入material npm包 npm install @angular/material @angular/cdk 2.新建一个ebiz-material.module.ts方便管理引入material的module ng g module ebiz-material -app=ebiz-ui 3.在app的根module中引入ebiz-material.module.ts import { EbizMaterialModule } from './ebiz-material/ebiz-m

  • angular6的table组件开发的实现示例

    背景及吐槽: 今年有机会再次接触angualr这个框架,想起第一次接触ng还是16年读书的时候,当时还是ng1,然后学起来特别辛苦,学习曲线特别陡峭:而今年有一个项目重构直接采用了angular6,而后面该项目后面由我负责开发和维护,然后我又重新再学习了ng6,本以为有ng1的基础,学起来会好一些,然并卵,学习的曲线特别陡峭,但还是最后将ng6啃下来(很不情愿去学的,但没办法).回归到项目,该项目没有引入其他组件库,所以很多基础组件都是自己开发(用ng开发那种酸爽很带劲),其中table组件让我

  • angular4自定义组件非input元素实现ngModel双向数据绑定的方法

    在angular里我们一般都是给input元素添加[(ngModel)]="value"实现数据双向绑定,如果想实现自定义的组件上实现ngModel双向数据绑定应该怎么办呐... 网上找了一下,没看懂记录一下. 场景:组件能获取父组件通过ngModel绑定的值,能通过ngModel改变父组件对应的数据.如下代码: <app-child [(ngModel])="appData"></app-child> 1.先贴出效果图: 2.下面是app-

  • Angular6新特性之Angular Material

    Angular Material是包含Navigation/Dashboard/Table三种图形类型,这篇文章中将会了解一些其使用的方式. 准备:安装Material 进入到上篇文章创建的demo2,使用ng add进行安装 liumiaocn:demo2 liumiao$ pwd /tmp/trainings/angualr/demo2 liumiaocn:demo2 liumiao$ 安装命令:ng add @angular/material liumiaocn:demo2 liumiao

  • Angular Material Icon使用详解

    1. 引入图标资源 在项目index.html文件里添加icon的图标库文件的引用. <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="external nofollow" rel="stylesheet"> 2. 导入MatIconModule 如果需要在别的组件同样使用,则需要exports里面引出. 3. icons 资源 可以访问

随机推荐