Component Development Kit
The Component Dev Kit (CDK) is a set of behavior primitives for building UI components.
存放组件以及命令的目录
项目组件中的公共方法集合地
里面封装了框架中使用到的共用组件和方法
Array
export function toArray<T>(value: T | T[]): T[] {
let ret: T[];
if (value == null) {
ret = [];
} else if (!Array.isArray(value)) {
ret = [value];
} else {
ret = value;
}
return ret;
}
export function arraysEqual<T>(array1: T[], array2: T[]): boolean {
if (!array1 || !array2 || array1.length !== array2.length) {
return false;
}
const len = array1.length;
for (let i = 0; i < len; i++) {
if (array1[i] !== array2[i]) {
return false;
}
}
return true;
}
export function shallowCopyArray<T>(source: T[]): T[] {
return source.slice();
}
Check
export function isNotNil<T>(value: T): value is NonNullable<T> {
return typeof value !== 'undefined' && value !== null;
}
export function isNil(value: unknown): value is null | undefined {
return typeof value === 'undefined' || value === null;
}
/**
* Examine if two objects are shallowly equaled.
*/
export function shallowEqual(objA?: any, objB?: any): boolean {
if (objA === objB) {
return true;
}
if (typeof objA !== 'object' || !objA || typeof objB !== 'object' || !objB) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
const bHasOwnProperty = Object.prototype.hasOwnProperty.bind(objB);
// tslint:disable-next-line:prefer-for-of
for (let idx = 0; idx < keysA.length; idx++) {
const key = keysA[idx];
if (!bHasOwnProperty(key)) {
return false;
}
if (objA[key] !== objB[key]) {
return false;
}
}
return true;
}
export function isNonEmptyString(value: any): boolean {
return typeof value === 'string' && value !== '';
}
convert
其中使用到了angular中的cdk/coercion
/**
* Get the function-property type's value
*/
export function valueFunctionProp<T>(prop: FunctionProp<T> | T, ...args: NzSafeAny[]): T {
return typeof prop === 'function' ? (prop as FunctionProp<T>)(...args) : prop;
}
function propDecoratorFactory<T, D>(name: string, fallback: (v: T) => D): (target: NzSafeAny, propName: string) => void {
function propDecorator(target: NzSafeAny, propName: string, originalDescriptor?: TypedPropertyDescriptor<NzSafeAny>): NzSafeAny {
const privatePropName = `$$__${propName}`;
if (Object.prototype.hasOwnProperty.call(target, privatePropName)) {
warn(`The prop "${privatePropName}" is already exist, it will be overrided by ${name} decorator.`);
}
Object.defineProperty(target, privatePropName, {
configurable: true,
writable: true
});
return {
get(): string {
return originalDescriptor && originalDescriptor.get ? originalDescriptor.get.bind(this)() : this[privatePropName];
},
set(value: T): void {
if (originalDescriptor && originalDescriptor.set) {
originalDescriptor.set.bind(this)(fallback(value));
}
this[privatePropName] = fallback(value);
}
};
}
return propDecorator;
}
/**
* Input decorator that handle a prop to do get/set automatically with toBoolean
*
* Why not using @InputBoolean alone without @Input? AOT needs @Input to be visible
*
* @howToUse
* ```
* @Input() @InputBoolean() visible: boolean = false;
*
* // Act as below:
* // @Input()
* // get visible() { return this.__visible; }
* // set visible(value) { this.__visible = value; }
* // __visible = false;
* ```
*/
export function InputBoolean(): NzSafeAny {
return propDecoratorFactory('InputBoolean', toBoolean);
}
export function InputCssPixel(): NzSafeAny {
return propDecoratorFactory('InputCssPixel', toCssPixel);
}
export function InputNumber(fallbackValue?: NzSafeAny): NzSafeAny {
return propDecoratorFactory('InputNumber', (value: string | number) => toNumber(value, fallbackValue));
}
ng-zorro-ant中使用的动画
<div
class="ant-collapse-content"
[class.ant-collapse-content-active]="nzActive"
[@.disabled]="noAnimation?.nzNoAnimation"
[@collapseMotion]="nzActive ? 'expanded' : 'hidden'"
>
<div class="ant-collapse-content-box">
<ng-content></ng-content>
</div>
</div>
自己使用动画
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { collapseMotion, fadeMotion, moveUpMotion } from 'ng-zorro-antd';
@Component({
selector: 'app-animations',
templateUrl: './animations.component.html',
styleUrls: ['./animations.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [collapseMotion],
})
export class AnimationsComponent implements OnInit {
isActive = false;
constructor() { }
ngOnInit() {}
}
点击.fade-header content内容就会展开
<div class="fade-header" (click)="isActive=!isActive">
<i nz-icon [nzType]="isActive ? 'down' : 'up'" nzTheme="outline"></i> Collapsed Header
</div>
<div class="content" [@collapseMotion]="isActive ? 'expanded' : 'hidden' ">
<p>content</p>
<p>content</p>
</div>
nz-tree-base-util.ts
export function isCheckDisabled(node: NzTreeNode): boolean {
const { isDisabled, isDisableCheckbox } = node;
return !!(isDisabled || isDisableCheckbox);
}
“!”是逻辑与运算,并且可以与任何变量进行逻辑与将其转化为布尔值,“!!”则是逻辑与的取反运算,尤其后者在判断类型时代码简洁高效,省去了多次判断null、undefined和空字符串的冗余代码
var a;
if(a!=null&&typeof(a)!=undefined&&a!=''){
//a有内容才执行的代码
}
// 等价于
if(!!a){
//a有内容才执行的代码...
}
内置了几种常用的颜色
export const presetColors = [
'pink',
'red',
'yellow',
'orange',
'cyan',
'green',
'blue',
'purple',
'geekblue',
'magenta',
'volcano',
'gold',
'lime'
] as const;
export type NzPresetColor = typeof presetColors[number];
export function isPresetColor(color: string): color is NzPresetColor {
return presetColors.indexOf(color as NzSafeAny) !== -1;
}