不再-封装-组件

世事总不能尽如人意。 就算强如 NG-ZORRO,虽然 99% 的情况下已经足够丰富,足够强大,足够恰当,但总有 %1 的情况,你会希望它能这样、或者那样就好了。 很多项目组都有 “封装” 组件的优良传统。理由有技术层面的,也有非技术层面的。我以前也没少干这事儿。有的时候是 nz-select 变成了 my-select、nz-date-picker 变成了 my-date-picker;有的时候是它们统统变成了 my-form-edit-control。 最后,我们获得了好处,也付出沉重的代价: 组件使用起来更加简单,但更加不灵活;组件 API 更加通用,但到最后程序往往不得不学习两套API;组件功能更加强大,但与原来的组件有哪些微妙的差别又很让人迷惑,到底该用哪个又总要纠结;有时候能有效屏蔽破坏性更新,但慢慢就开始阻碍进步……怎么破? 轻量级、装饰模式、单一职责 这是软件领域最美妙的几个词儿之一,而且它们很适合用来形容 Angular 的指令。 例如,如果我们希望卡片组件能自适应页面的高度,就可以写一个名为 nsAutoHeightCard 的指令 源码 demo,将其 “装饰” 到 nz-card 组件上,就实现了自适应页面高度的卡片。 <nz-card nsAutoHeightCard nzTitle="自适应高度卡片"> <p>Card content</p> </nz-card> DRY NG-ZORRO 作为组件库,保持组件模型的简单、直接没有问题。但我们在实际的工程实践中,需要更大程度地遵循 DRY(Don’t Repeat Yourself) 原则,以表单验证为例: 对于必填项等常规表单验证显示错误信息的功能,应该统一处理,而不是在每个表单中将错误信息重复一遍。既然已经在 FormGroup 对象中配置了验证条件,表单组件最好能根据这些条件自动配置验证视觉反馈,而不用再在表单组件中重复配置 nzRequired 和 nzHasFeedback。我们可以通过无脑统一给每个组件增加 nsAutoFeedback 和 nsErrorTip 指令 源码1 源码2 demo,就可以将上述那些繁琐枯燥还易错的工作全部自动完成,甚至还能自动为标签和编辑组件增加 nzFor 和 id 属性: <nz-form-item *nsAutoFeedback> <nz-form-label [nzSpan]="8">用户名</nz-form-label> <nz-form-control nsErrorTip nzSpan="16"> <input nz-input formControlName="userText" /> </nz-form-control></nz-form-item> ...

September 9, 2019 · 1 min · jiezi

ngzorro组件库日期组件禁止手动输入日期

在使用ng-zorro组件库中的日期控件时,遇到区间输入日期时间的一系列bug,后需要将日期控件禁止手动输入,因为没有相关api所以利用jq操作dom解决1.引入jq库,2.使用日期组件的nzOpenChange事件,在日期面板打开时操作dom将输入框隐藏掉即可

June 18, 2019 · 1 min · jiezi

ngalain重置表单cascader不生效

ng-alain 使用SF formReset重置搜索表单时,级联组件cascader不生效,文字没被清空?在使用ng-alain生成的列表模板中,上面是由动态表单组件SF构成。下面是由ST表格组件构成。下面说说ST表格的上方的搜索表单组件SF。 在使用过程中,SF动态表单可以随意配置已有的小部件,大多小部件都很实用并且常用,但有个别小部分存在缺陷问题,如cascader级联组件。你可能会遇到以下的小问题: 当表单都存在数据时,进行重置操作,使用SF的(formReset)方法,但出来的效果除了级联组件cascader内容没清空外,其他小部件都清空了原有的值。此时再调用SF的(formSubmit)方法,发现原来cascader的值是空的,而组件所显示文字却没有被清空。 此时解决办法如下:在(formReset)方法中刷新SF的schema来实现清空。 html文件 <page-header [action]="phActionTpl" [breadcrumb]="breadcrumb"></page-header><nz-card> <sf #sf mode="search" [schema]="searchSchema" [ui]="uiSchema" [button]="sfButton" (formSubmit)="search($event)" (formReset)="reset($event)"></sf> <st #st [data]="url" [columns]="columns"></st></nz-card>ts文件 /** * 搜索 * @param event 搜索表单数据对象 */search(event) { console.log(event) this.st.load(undefined, event)}/*** 搜索重置 * @param event 搜索表单数据对象 */reset(event) { this.st.reset(event); // 针对级联组件cascader不能清空的问题,重新refresh一次表单 this.sf.refreshSchema();}

May 16, 2019 · 1 min · jiezi

使用ng-zorro图标库部分图标不能正常显示

在ng-alain中,使用ng-zorro图标库,发现部分能正常显示,部分并不能显示,在控制台同时发现出错报错。ERROR Error: [@ant-design/icons-angular]: the icon redo-o does not exist or is not registered.at IconNotFoundError (ant-design-icons-angular.js:159)at MapSubscriber.project (ant-design-icons-angular.js:343)...出现以上问题是没有对相对的图标进行导入,并导出。ng-alain默认只导入了图标库的几十个图标,在 style-icons-auto.ts可进行查看。 因此可以参考style-icons-auto.ts,把你所需要的图标进行import and exportng-zorro图标库:https://ng.ant.design/compone...

April 22, 2019 · 1 min · jiezi

Angular中修改第三方组件的样式 - zorro日期选择器右端不对齐的BUG

在一列上同时使用zorro的日期选择器和input组件会出现右端不对齐的BUG(nzSpan设置为一样)上图中3个表单项:单据日期、开票、交货方式,nzSpan数值是一样的,可以看到日期选择器和下面的“交货方式”右端没有对齐在浏览器控制台中层层展开后到达下面的路径:可以看到ant-calendar-picker是日期选择器组件的官方提供的样式,在该样式下手动追加属性width:100%,右端就可以对齐了,那么接下来只要应用到源码中就好了结果在当前组件的css文件中直接.ant-calendar-picker{width:100%;}是没有效果的,要这样使用才有效:::ng-deep .ant-calendar-picker{width:100%;}

February 20, 2019 · 1 min · jiezi

Angular7 ng-zorro-antd 制作右键菜单

没多少逻辑,就直接贴代码了下面是html模板的代码:<ul nz-menu [style.width]=“300” [nzTheme]="‘dark’" [nzMode]="‘inline’" [nzInlineCollapsed]=“isCollapsed”> <li nz-menu-item (contextmenu)=“contextMenu($event, contextTemplate)">中国</li> <li nz-menu-item (contextmenu)=“contextMenu($event, contextTemplate)">美国</li> <li nz-menu-item (contextmenu)=“contextMenu($event, contextTemplate)">英国</li></ul><ng-template #contextTemplate> <ul nz-menu nzInDropDown nzSelectable (nzClick)=“close()"> <li nz-menu-item (click)=“openRenameListModal()"> <i class=“anticon anticon-edit anticon-right-margin”></i> <span>重命名</span> </li> <li nz-menu-divider></li> <li nz-menu-item (click)=“delete()"> <i class=“anticon anticon-delete anticon-right-margin danger”></i> <span class=“danger”>删除列表</span> </li> </ul></ng-template>下面是ts文件的代码import { Component, TemplateRef } from ‘@angular/core’;import { FormsModule } from ‘@angular/forms’;import { NzDropdownContextComponent, NzDropdownService } from ’ng-zorro-antd’;@Component({ selector: ‘app-root’, templateUrl: ‘./app.component.html’, styleUrls: [’./app.component.css’]})export class AppComponent { constructor( private dropdownService:NzDropdownService ){} dropdown:NzDropdownContextComponent; contextMenu($event:MouseEvent,template:TemplateRef<void>){ this.dropdown=this.dropdownService.create($event,template); } openRenameListModal(){ console.log(“打开了重命名modal”); } close(){ this.dropdown.close(); } delete(){ console.log(“删除了一个元素”); }} ...

February 14, 2019 · 1 min · jiezi

使用Angular自定义字段校验指令

Angular中,提供的表单验证不能用于所有应用场景,就需要创建自定义验证器,比如对IP、MAC的合法性校验 这里是根据官网实例自定义MAC地址的正则校验,环境为Angular: 7.2.0 , NG-ZORRO:v7.0.0-rc3添加指令/shared/validator.directive.ts注册到 NG_VALIDATORS 提供商中providers: [ {provide: NG_VALIDATORS, useExisting: ValidatorDirective, multi: true} ]Angular 在验证流程中的识别出指令的作用,是因为指令把自己注册到了 NG_VALIDATORS 提供商中,该提供商拥有一组可扩展的验证器。实现 Validator 接口import {Directive, Input} from ‘@angular/core’;import {Validator, AbstractControl, NG_VALIDATORS} from ‘@angular/forms’;@Directive({ selector: ‘[appValidator]’, providers: [ {provide: NG_VALIDATORS, useExisting: ValidatorDirective, multi: true} ]})export class ValidatorDirective implements Validator { @Input(‘appValidator’) value: string; validate(control: AbstractControl): { [key: string]: any } | null { const validateMac = /^(([A-Fa-f0-9]{2}[:]){5}[A-Fa-f0-9]{2}[,]?)+$/; switch (this.value) { case ‘mac’: return validateMac.exec(control[‘value’]) ? null : {validate: true}; break; } }}ValidatorDirective写好后,只要把 appValidator 选择器添加到输入框上就可以激活这个验证器。在模板中使用<nz-form-item> <nz-form-control> <nz-input-group> <input formControlName=“mac” nz-input type=“text” placeholder=“mac” appValidator=“mac”> </nz-input-group> <nz-form-explain *ngIf=“validateForm.get(‘mac’).dirty && validateForm.get(‘mac’).errors”> 请输入正确的Mac地址! </nz-form-explain> </nz-form-control> </nz-form-item>在mac地址校验不通过时,错误信息便会显示。如果想在失去焦点时显示错误信息可以使用validateForm.get(‘mac’).touched,如下:<nz-form-explain *ngIf=“validateForm.get(‘mac’).dirty && validateForm.get(‘mac’).errors&&validateForm.get(‘mac’).touched”> 请输入正确的Mac地址! </nz-form-explain>到此,自定义字段验证指令就完成了,更多请查看Angular官网表单验证自定义验证器部分。 ...

January 31, 2019 · 1 min · jiezi

ng-zorro使用心得

前言本周使用ng-zorro做了项目的原型,对它也有了一定的了解,总的来说不难,可以用强化版boostrap来理解它,由于黄庭祥初始化工作做得很好,在写的过程遇到的问题不是很麻烦,感谢祥哥。问题一、button不起作用问题描述:button按钮按下无响应,如下图:图片描述代码如下:解决思路:首先删除button中所有的样式,保留最基本的html,发现依然无响应,说明问题不在button身上排查栅格布局,发现table标签被我放在了button同一行新建了一个row,col放置table,问题解决总结:看来ng-zorro的栅格要比bootstrp严格,不允许随便嵌套内容问题二、routerLink不起作用问题描述:在button中使用routerLink无法进行页面跳转代码如下<button nz-button routerLink="/main/grade/add"><i nz-icon type=“plus”></i>增加</button>解决思路:打开控制台,点击button,发现无报错信息将跳转方式改成a标签的herf,发现可以跳转,说明url定义无误询问黄庭祥,检查,发现我没有在父组件中写<router-outlet></router-outlet>缺少路由出口,将其添加,问题解决搜索栏button不对齐问题描述:在使用官方文档的一个搜索框时,样式与官方文档不一致官方的样式:复制过来以后的样式:可以看到button没有附着在input上解决思路:打开检查,寻找该控件的css样式发现去除该处样式,button的位置恢复正常原因:该样式是我自己添加的,为了能让多个button间有空隙,但却覆盖了搜索框button的样式,最后去除该样式,用 来实现button间的空隙问题四、 左侧导航栏无法向下滚动问题描述:当左侧导航栏内容超出页面时,无法滚动下滑,如下图:解决思路:查看官方文档的示例代码,对比参考,看不出异常谷歌搜索"ng-zorro submenu overflowed",结果太少将我们的导航栏的代码全部注释,换成官方的示例代码,发现问题依然存在,说明我们侧导航栏的样式写得有问题打开检查,排查css样式,发现是position fix惹的祸,将其去除后,导航可以滚动总结本周写原型的工作并不复杂,主要是在看文档理解需求上遇到一些问题,经常返工重做,另外,感觉ng-zorro的官方文档写得不是很全,在写一些功能时经常需要猜,而且一旦改动样式就会出现一些不可预料的错误。

December 1, 2018 · 1 min · jiezi

Release ng-alain 2.0

从计划2.0开始足足进行近四个月,其中发布过八个版本。当初给2.0做的愿景基本上达到要求,当然一切都还是那句话:【让开发者更加专注于业务】。ng-zorro-antd 提供的大量的基础组件,当你熟悉这些组件以后,开发 Angular 会是一种“爽”体验,然而对于中后台而言部分高频繁组件在大多数场景下显得有点臃肿。所以 2.0 变更主要从两个方面:使 CURD 操作更“自然”开发体验更友好响应式开发CURD提供一组 Simple 系列组件:sv:查看se:编辑st:数据表格(原 simple-table 重新重构)以及基于 JSON Schema 的动态表单 sf,这四个 Simple 系列组件相比较 ng-zorro-antd 的原始写法,更易编写、阅读,基本上可以满足大多数场景;但它们并非用来替代原始的写法,特别是 st 与 sf 它们并不适合复杂交互,此时,依然应该优先使用原始方式。除此之外,2.0 对部分输入属性及接口的多态性、内聚性做一些变更。属性多态性当构建一个数据表格时,表格的数据源可能来自远程数据或本地静态数据,但我们不应该过度的将数据源做成两个不同属性加以区分,他们只是不同的数据来源而已,但对于表格而言是统一:<table [data]=“url”></table><table [data]=“list”></table>属性内聚性同一个功能的属性应该更内聚,例如我们表述一个HTTP请求时,包含:请求方法、请求域、参数等,这些属性应该统一在一个对象值体现,HttpClient 请求就是一个非常好的例子。<st [reqMethod]="‘GET’" [reqParams]="{ a: 1 }"></st><st [req]="{ method: ‘get’, params: { a: 1 } }"></st>响应式开发意指开发过程中如何使用最小的方式构建符合移动端的中后台,ng-alain 默认提供一套 响应式服务 规则,它服务于最基础的CURD组件:se、sv 等。例如:当你希望构建一行两列的表单,并且若屏幕小于 <576px 将自动转化成一列,则只需要这样:<div se-container=“2”> <se label=“Field1”></se> <se label=“Field2”></se></div>当然这一切只是简化 nz-row、nz-col 的运用而已,如果你希望布局也延续这种方式可以使用 sg 组件。除此之外,ng-alain 也将 CSS 做为开发语言非常重要的组成部分,并且将这些语言特征转化成独立的单元类,如果你是采用 VSCODE 可借由 ng-alain snippets 提供的智能提醒,减少理解它们的成本。升级Angular Cli 提供的 ng update 命令让我们可以大胆重构、改进你的组件,并且用户升级只需要简单的一行命令就可以完全升级。从 1.x 升级至 2.x 虽然无法改变 ts 代码方面的动作,但基本上可以完成 HTML 方面的升级,主要还是 ts 代码的解析无法像 HTML 那样预期。而 ng-alain 的 1.x 升至 2.0 也只需要一行命令而已,有关更多细节,请参考升级指引。未来直到 ng-zorro-antd 下一大版本更新之前,2.0 保持一段时间的休息期,不再会有新功能。之后,会根据 ng-zorro-antd 的进度,对 ng-alain 做一次大的性能重构。新尝试ng-alain 正在尝试提供商业主题服务,有兴趣可以参阅。(完) ...

November 21, 2018 · 1 min · jiezi

如何更好使用 ng-zorro-antd 图标

自 ng-zorro-antd 1.7.x 以后图标发生破坏性变更,虽然带了诸多优势,同时也带来几个劣势:若采用动态加载会产生额外的HTTP请求若静态加载需要逐一注册图标st 组件的 format 参数无法直接指定图标ng-alain 默认使用静态加载的做法,毕竟后端使用图标相对于比较有限,即使将 svg 都打包进脚本相比较之前整个 styles 体积上是所有减少,但比较并不多。而针对以上问题,ng-alain 提供几种方案。使用icon插件(推荐)尽可能从项目中分析并生成静态 Icon,插件会自动在 src 目录下生成两个文件:src/style-icons.ts 自定义部分无法解析(例如:远程菜单图标)src/style-icons-auto.ts 命令自动生成文件自动排除 ng-zorro-antd 和 @delon 已经加载的图标。ng g ng-alain:plugin icon同时,需要手动在 startup.service.ts 中导入:import { ICONS_AUTO } from ‘../../../style-icons-auto’;import { ICONS } from ‘../../../style-icons’;@Injectable()export class StartupService { constructor(iconSrv: NzIconService) { iconSrv.addIcon(…ICONS_AUTO, …ICONS); }}有效语法<i class=“anticon anticon-user”></i><i class=“anticon anticon-question-circle-o”></i><i class=“anticon anticon-spin anticon-loading”></i><i nz-icon class=“anticon anticon-user”></i><i nz-icon type=“align-{{type ? ’left’ : ‘right’}}"></i><i nz-icon [type]=“type ? ‘menu-fold’ : ‘menu-unfold’” [theme]=“theme ? ‘outline’ : ‘fill’"></i><i nz-icon [type]=“type ? ‘fullscreen’ : ‘fullscreen-exit’"></i><i nz-icon type=”{{ type ? ‘arrow-left’ : ‘arrow-right’ }}"></i><i nz-icon type=“filter” theme=“outline”></i><nz-input-group [nzAddOnBeforeIcon]=“focus ? ‘anticon anticon-arrow-down’ : ‘anticon anticon-search’"></nz-input-group>动态加载动态加载,这是为了减少包体积而提供的方式。当 NG-ZORRO 检测用户想要渲染的图标还没有静态引入时,会发起 HTTP 请求动态引入。你只需要配置 angular.json 文件:{ “assets”: [ { “glob”: “**/*”, “input”: “./node_modules/@ant-design/icons-angular/src/inline-svg/”, “output”: “/assets/” } ]}动态使用不管是静态或动态加载,依然无法解决原始方法 class=“anticon anticon-” 的便利性,毕竟字符串就是字符串并非 Angular 模板无法被解析,而针对这个问题,提供两种解决办法。类样式事实上所有 Antd 图标都可以在 iconfont 找得到,可以点选自己需要的图标并生成相应的 css 文件或 cdn,最后在项目中可以直接使用 1.7.0 之前的写法。注意: 在项目编辑里加上 anticon anticon- 前缀才能同之前的类名保持一致。// angular.json"styles”: [ “src/iconfont.css”],如果非cnd还需要将相应的 icon 图标文件复制到 assets 目录下,同时修改 iconfont.css 中 @font-face 对应的 url 路径。@angular/elements动态加载的另一种方式是使用 @angular/elements,只需要 nz-icon 指令重新封装成组件。import { Component, Input } from ‘@angular/core’;@Component({ selector: ’nz-icon’, template: &lt;i nz-icon [type]="type"&gt;&lt;/i&gt;,})export class IconComponent { @Input() type: string;}同时在根模块里注册它。import { createCustomElement } from ‘@angular/elements’;@NgModule({ declarations: [], entryComponents: []})export class AppModule { constructor(injector: Injector) { customElements.define(’nz-icon’, createCustomElement(IconComponent, { injector })); }}最后。@Component({ selector: ‘app-demo’, template: &lt;div [innerHTML]="value"&gt;&lt;/div&gt; ,})export class DemoComponent { constructor(private san: DomSanitizer) { } value = this.san.bypassSecurityTrustHtml( icon: &lt;nz-icon type="bell"&gt;&lt;/nz-icon&gt;, );}结论本文只是针对这一次 ng-zorro-antd 图标上的变更做一个总结,就我个人而言还是比较推荐静态加载的方式,这无关乎包体大小的问题,而是更加明确我需要什么所以我应加载什么。 ...

October 26, 2018 · 1 min · jiezi