@acimini/cm-utils 中文文档教程

发布于 4年前 浏览 18 项目主页 更新于 3年前

CmUtils

CmUtils 是一个库,包含一些用于管理对象和数组的实用函数。\ 有了这个库,我们有:

  • functions and pipes that check if an element is undefined, null or empty (they work on objects, arrays and variables)
  • function to merge two objects or two arrays
  • function to clone an object
  • functions to remove duplicates in an array and check if two elements are equal
  • function to convert a json (maybe from an api) to a specific typescript class and vice versa
  • functions to find, update and remove properties deep into an object

这是基于:

Index

  1. Install
  2. How to use
  3. Utility functions
  4. Pipes
  5. Authors
  6. License

Install

npm install @acimini/cm-utils --save

在你的应用程序

import { CmUtilsModule } from '@acimini/cm-utils';

@NgModule({
  imports: [ CmUtilsModule ],
  ...
})

How to use

First define your model

 import {CmUtilsProperty} from '@acimini/cm-utils';

 class SubClassName {
   @CmUtilsProperty(String) subkey1: string;
   @CmUtilsProperty(Boolean) subkey2: boolean;
 }

 class ClassName {
   @CmUtilsProperty(String) key1: string;
   @CmUtilsProperty(SubClassName) key2: SubClassName;
   @CmUtilsProperty(Number) key3: number;
   @CmUtilsProperty(String) key4: string[];
   @CmUtilsProperty(SubClassName) key5: SubClassName[];
 }

中导入 CmUtilsProperty 装饰器中的第一个参数告诉实用程序函数属性的类型是什么.\ 在比较打字稿类型和装饰器类型的表格下方:

Decorator typeTypeScript type
Stringstring
Numbernumber
Booleanboolean
ClassNameClassName
Anyany
Multimulti types
Tupletuple types
Multi types

多类型用于那些可以同时具有多种类型的变量。 例如,可以是字符串或数字的变量。\ 在这种情况下,模型定义将是

 import {CmUtilsProperty, Multi} from '@acimini/cm-utils';

 class ClassName {
   @CmUtilsProperty(new Multi(String, Number)) key1: string | number;
 }
Tuple types

元组类型,这些变量是具有定义数量的不同类型元素的数组。 例如,一个变量是一个数组,第一个元素为字符串,第二个元素为数字。\ 在这种情况下,模型定义将

 import {CmUtilsProperty, Tuple} from '@acimini/cm-utils';

 class ClassName {
   @CmUtilsProperty(new Tuple(String, Number)) key1: [string, number];
 }

Use utility functions

 import {CmUtilsService} from '@acimini/cm-utils';

 const firstObj = new ClassName();
 const secondObj = new ClassName();
 ...

 const newObj = CmUtilsService.mergeObj(firstObj, secondObj);
 ...

Utility functions

isUndefined

检查元素是否未定义。

 const elem = new ClassName();
...
 CmUtilsService.isUndefined(elem) 

如果未定义则返回 true,否则返回 false

isNull

检查元素是否为 null。

 const elem = new ClassName();
...
 CmUtilsService.isNull(elem) 

如果它为 null,则返回 true,否则返回 false

isNil

检查元素是否为 null 或未定义。

 const elem = new ClassName();
...
 CmUtilsService.isNil(elem) 

如果未定义或为 null,则返回 true,否则返回 false

isEmpty

检查元素是否为空。 它可以与字符串、数组和对象一起使用。

 const elem = new ClassName();
...
 CmUtilsService.isEmpty(elem) 

如果它为空则返回 true,否则返回 false

isNilty

检查元素是否为 null 或 undefined 或为空。 它可以与字符串、数组和对象一起使用。

 const elem = new ClassName();
...
 CmUtilsService.isNilty(elem)

如果它是未定义的或 null 或空的,它返回 true,否则返回 false

merge

合并两个项目(数组或对象)。

 const firstItem: ClassName = new ClassName();
 const secondItem: ClassName = new ClassName();
...
 CmUtilsService.merge(firstItem, secondItem)

它将第一项合并到第二项中。

array merge strategy

默认情况下,数组被合并到目标数组中,将那些在源数组中但不在目标数组中的元素推送到目标数组中。 例如:

[1,3,5] merge into [1,2,3] become [1,2,3,5]

可以通过两种方式改变这种行为:

  • passing a merger function as third parameter in merge method
  • passing a merger function into CmUtilsProperty decorator

在这两种情况下合并函数必须以这种方式定义:

function merger (item, sourceArray, destinationArray) {
    // do something 
}

如果我们调用 merge 方法合并两个数组,或者我们想要合并两个对象并对数组的所有属性应用相同的合并策略,则第一种情况很有用。

function merger (item, sourceArray, destinationArray) {
    // do something 
}

CmUtilsService.merge(firstArray, secondArray, merger)

如果我们想要合并两个对象并对不同的属性应用不同的合并策略,则第二种情况很有用。

class ClassName {
   @CmUtilsProperty(String) key1: string;
   @CmUtilsProperty(Number) key2: number;
   @CmUtilsProperty(String, {arrayMerger: merger}) key3: string[];
 }

function merger (item, sourceArray, destinationArray) {
    // do something 
}

const firstObject: ClassName = new ClassName();
const secondObject: ClassName = new ClassName();

CmUtilsService.merge(firstObject, secondObject)

可以将自定义合并定义为合并方法的第三个参数,并将其他合并定义为装饰器中的属性。\ 在这种情况下,将使用第一次合并,直到该属性没有自己的为止。

cloneClass

克隆具有特定类的对象。 \ 可以将不同的类作为第二个参数传递。 如果未提供,则克隆的对象将具有与用于克隆的对象相同的类。

 const obj: ClassName = new ClassName();
...
 CmUtilsService.cloneClass(obj, optionalClass)

它返回克隆的对象。

注意:当用于克隆的类比结果对象的类具有更多或更少的属性时,第二个参数很有用,并且共同的属性具有相同的类型。 这意味着如果共同的属性具有不同的类型,则此方法无用(对于这种情况,请检查序列化程序方法)。

isEqual

检查两个项目是否相等。

 const firstElem: ClassName = new ClassName();
 const secondElem: ClassName = new ClassName();
...
 CmUtilsService.isEqual(firstElem, secondElem)

如果元素相等则返回 true,否则返回 false。

uniqueBy

检查数组中的重复项并将其删除。 \ 可以使用函数来定义用于删除相等元素的策略(例如,我们希望删除对特定键具有相同值的元素)。 如果未提供,将使用默认值,并且仅删除完全相等的元素。

 const array: ClassName[] = [];
...
 CmUtilsService.uniqueBy(array, optionalFunction)

deserialize

将 json 转换为特定类(它也可用于将类转换为另一个类)。

 const json = {};
...
 CmUtilsService.deserializer(json, ClassName)

它返回反序列化的对象。

property decorator configuration

如果 json 中的属性与 ClassName 中的属性相同(对于名称和类型)装饰器配置是默认配置:

 class ClassName {
   @CmUtilsProperty(String) key1: string;
 }

如果 json 中的属性具有不同的类型或名称或两者,装饰器配置将是:

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, propertyKey: 'key1different'}) key1: string;
 }

propertyType 定义类型,propertyKey 定义 json 对象中属性的名称。 \ 如果 propertyType 不是原始类型(请参阅如何使用 部分中的表格),或者有必要这样做转换值的一些操作,可以定义自定义转换器。 \

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, converter: new NumberToStringConverter()}) key1: string;
 }

其中 converter 必须以这种方式定义:

class NumberToStringConverter implements CustomConverter<String> {
  serialize(data: String): any {
  }

  deserialize(data: any): String {
    return data.toString().replace('.', ',');
  }

}

每个 converter 必须实现 CustomConverter 接口并且必须有两个方法:

deserialize 方法< /strong> 获取属性的 json 值并返回转换后的值。

注意:转换器也可以在数组和对象类型属性上定义。 \ 在这种情况下,相同的转换器应用于没有自己的转换器的数组/对象的每个元素/属性。

serialize

将特定类转换为 json。

 class ClassName {
  ...   
 }
...
 CmUtilsService.serializer(ClassName)

它返回序列化的 json。

property decorator configuration

如果 ClassName 中的属性与 json 中的属性相同(名称和类型),则装饰器配置为默认配置:

 class ClassName {
   @CmUtilsProperty(String) key1: string;
 }

如果 ClassName 中的属性具有不同的类型或名称或两者,装饰器配置将是:

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, propertyKey: 'key1different'}) key1: string;
 }

propertyType 定义类型,propertyKey 定义 json 对象中属性的名称。 \ 如果 propertyType 不是原始类型(请参阅如何使用 部分中的表格),或者有必要这样做转换值的一些操作,可以定义自定义转换器。 \

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, converter: new NumberToStringConverter()}) key1: string;
 }

其中 converter 必须以这种方式定义:

class NumberToStringConverter implements CustomConverter<Number> {
  serialize(data: String): Number {
    return Number(data.replace(',', '.'));
  }

  deserialize(data: Number): String {
    return undefined;
  }

}

每个 converter 必须实现 CustomConverter 接口并且必须有两个方法:

serialize 方法< /strong> 获取属性的 ClassName 值并返回转换后的值。

注意:转换器也可以在数组和对象类型属性上定义。 \ 在这种情况下,相同的转换器应用于没有自己的转换器的数组/对象的每个元素/属性。

deepFind

给定一个对象,返回特定路径处的属性值。

 const obj = new ClassName();
...
 CmUtilsService.deepFind(obj, 'path.to.key')

注意:路径必须从对象的根开始,每一层必须用点分隔。 \ 对于数组,键是元素的索引。

deepUpdate

给定一个对象,更新特定路径处的属性值。

 const obj = new ClassName();
...
 CmUtilsService.deepUpdate(obj, 'path.to.key', newValue)

注意:路径必须从对象的根开始,每一层必须用点分隔。 \ 对于数组,键是元素的索引。

deepRemove

给定一个对象,删除特定路径处的属性。

 const obj = new ClassName();
...
 CmUtilsService.deepRemove(obj, 'path.to.key')

注意:路径必须从对象的根开始,每一层必须用点分隔。 \ 对于数组,键是元素的索引。

Pipes

该库还提供以下管道:

  • isUndefined: check if element is undefined
  • isNull: check if element is null
  • isNil: check if element is null or undefined
  • isEmpty: check if element is empty
  • isNilty: check if element is null or undefined or empty

Authors

  • Andrea Cimini

License

该项目已获得 Apache License 2.0 许可 - 有关详细信息,请参阅 LICENSE.md 文件。

CmUtils

CmUtils is a library that contains some utility functions to manage objects and arrays.\ With this library we have:

  • functions and pipes that check if an element is undefined, null or empty (they work on objects, arrays and variables)
  • function to merge two objects or two arrays
  • function to clone an object
  • functions to remove duplicates in an array and check if two elements are equal
  • function to convert a json (maybe from an api) to a specific typescript class and vice versa
  • functions to find, update and remove properties deep into an object

This is based on:

Index

  1. Install
  2. How to use
  3. Utility functions
  4. Pipes
  5. Authors
  6. License

Install

npm install @acimini/cm-utils --save

Import in your app

import { CmUtilsModule } from '@acimini/cm-utils';

@NgModule({
  imports: [ CmUtilsModule ],
  ...
})

How to use

First define your model

 import {CmUtilsProperty} from '@acimini/cm-utils';

 class SubClassName {
   @CmUtilsProperty(String) subkey1: string;
   @CmUtilsProperty(Boolean) subkey2: boolean;
 }

 class ClassName {
   @CmUtilsProperty(String) key1: string;
   @CmUtilsProperty(SubClassName) key2: SubClassName;
   @CmUtilsProperty(Number) key3: number;
   @CmUtilsProperty(String) key4: string[];
   @CmUtilsProperty(SubClassName) key5: SubClassName[];
 }

The first parameter in CmUtilsProperty decorator tells to utility functions what is the type of the property.\ Below the table that compares the typescript type with the type for the decorator:

Decorator typeTypeScript type
Stringstring
Numbernumber
Booleanboolean
ClassNameClassName
Anyany
Multimulti types
Tupletuple types
Multi types

Multi types are used for those variables that can have multi types at same time. For example a variable that can be a string, or a number.\ In this case model definition will be

 import {CmUtilsProperty, Multi} from '@acimini/cm-utils';

 class ClassName {
   @CmUtilsProperty(new Multi(String, Number)) key1: string | number;
 }
Tuple types

Tuple types are used for those variables that are arrays with defined number of elements of different types. For example a variable that is an array with first element as string and second element as number.\ In this case model definition will be

 import {CmUtilsProperty, Tuple} from '@acimini/cm-utils';

 class ClassName {
   @CmUtilsProperty(new Tuple(String, Number)) key1: [string, number];
 }

Use utility functions

 import {CmUtilsService} from '@acimini/cm-utils';

 const firstObj = new ClassName();
 const secondObj = new ClassName();
 ...

 const newObj = CmUtilsService.mergeObj(firstObj, secondObj);
 ...

Utility functions

isUndefined

Checks if an element is undefined.

 const elem = new ClassName();
...
 CmUtilsService.isUndefined(elem) 

It returns true if it is undefined, false otherwise

isNull

Checks if an element is null.

 const elem = new ClassName();
...
 CmUtilsService.isNull(elem) 

It returns true if it is null, false otherwise

isNil

Checks if an element is null or undefined.

 const elem = new ClassName();
...
 CmUtilsService.isNil(elem) 

It returns true if it is undefined or null, false otherwise

isEmpty

Checks if an element is empty. It can be used with strings, arrays and objects.

 const elem = new ClassName();
...
 CmUtilsService.isEmpty(elem) 

It returns true if it is empty, false otherwise

isNilty

Checks if an element is null or undefined or empty. It can be used with strings, arrays and objects.

 const elem = new ClassName();
...
 CmUtilsService.isNilty(elem)

It returns true if it is undefined or null or empty, false otherwise

merge

Merge two items (arrays or objects).

 const firstItem: ClassName = new ClassName();
 const secondItem: ClassName = new ClassName();
...
 CmUtilsService.merge(firstItem, secondItem)

It merges the first item into the second item.

array merge strategy

By default, array are merged pushing in destination array those elements that are in source array and aren't in destination array. For example:

[1,3,5] merged into [1,2,3] become [1,2,3,5]

It's possible to change this behaviour in two ways:

  • passing a merger function as third parameter in merge method
  • passing a merger function into CmUtilsProperty decorator

In both cases merger function must be defined in this way:

function merger (item, sourceArray, destinationArray) {
    // do something 
}

First case is useful if we call merge method to merge two arrays, or we want to merge two objects and apply the same merge strategy for all properties that are arrays.

function merger (item, sourceArray, destinationArray) {
    // do something 
}

CmUtilsService.merge(firstArray, secondArray, merger)

Second case is useful if we want to merge two objects and apply different merge strategy for different properties.

class ClassName {
   @CmUtilsProperty(String) key1: string;
   @CmUtilsProperty(Number) key2: number;
   @CmUtilsProperty(String, {arrayMerger: merger}) key3: string[];
 }

function merger (item, sourceArray, destinationArray) {
    // do something 
}

const firstObject: ClassName = new ClassName();
const secondObject: ClassName = new ClassName();

CmUtilsService.merge(firstObject, secondObject)

It is possible both define a custom merger as third parameter of the merge method and other mergers as property in decorators.\ In this case the first merger is used until the property doesn't have its own.

cloneClass

Clone an object with specific class. \ It is possible to pass, as second parameter, a different class. If it is not provided, the cloned object will have the same class of that used for cloning.

 const obj: ClassName = new ClassName();
...
 CmUtilsService.cloneClass(obj, optionalClass)

It returns the cloned object.

N.B. The second parameter is useful when the class used for cloning has more or fewer properties than the class of the result object, and the properties in common have the same types. This means that this method is useless if the properties in common have different types (for that case check the serializer method).

isEqual

Checks if two items are equal.

 const firstElem: ClassName = new ClassName();
 const secondElem: ClassName = new ClassName();
...
 CmUtilsService.isEqual(firstElem, secondElem)

It returns true if the elements are equal, false otherwise.

uniqueBy

Check for duplicates in array and remove them. \ It is possible to use a function to define the strategy used to remove equal elements (for example we want remove the elements that have the same value for a specific key). If it is not provided, the default one will be used and only the elements perfectly equal will be removed.

 const array: ClassName[] = [];
...
 CmUtilsService.uniqueBy(array, optionalFunction)

deserialize

Convert a json into a specific class (it can be used also to convert class into another).

 const json = {};
...
 CmUtilsService.deserializer(json, ClassName)

It returns the deserialized object.

property decorator configuration

If the property in json is the same (for the name and type) of the property in ClassName the decorator configuration is the default one:

 class ClassName {
   @CmUtilsProperty(String) key1: string;
 }

If the property in json has different type or name or both, the decorator configuration will be:

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, propertyKey: 'key1different'}) key1: string;
 }

Where propertyType defines the type and propertyKey defines the name of the property in the json object. \ In case of the propertyType is not a primitive type (see table in How to use section), or it is necessary to do some operation to convert the value, it is possible define a custom converter. \

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, converter: new NumberToStringConverter()}) key1: string;
 }

Where converter must be defined in this way:

class NumberToStringConverter implements CustomConverter<String> {
  serialize(data: String): any {
  }

  deserialize(data: any): String {
    return data.toString().replace('.', ',');
  }

}

Each converter must implement CustomConverter interface and must have two methods:

The deserialize method takes the json value of the property and returns the transformed value.

N.B.: The converter can be defined also on an array, and an object type property. \ In this case, the same converter is applied on each element/property of the array/object that doesn't have its own converter.

serialize

Convert a specific class into a json.

 class ClassName {
  ...   
 }
...
 CmUtilsService.serializer(ClassName)

It returns the serialized json.

property decorator configuration

If the property in ClassName is the same (for the name and type) of the property in json the decorator configuration is the default one:

 class ClassName {
   @CmUtilsProperty(String) key1: string;
 }

If the property in ClassName has different type or name or both, the decorator configuration will be:

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, propertyKey: 'key1different'}) key1: string;
 }

Where propertyType defines the type and propertyKey defines the name of the property in the json object. \ In case of the propertyType is not a primitive type (see table in How to use section), or it is necessary to do some operation to convert the value, it is possible define a custom converter. \

 class ClassName {
   @CmUtilsProperty(String, undefined, {propertyType: Number, converter: new NumberToStringConverter()}) key1: string;
 }

Where converter must be defined in this way:

class NumberToStringConverter implements CustomConverter<Number> {
  serialize(data: String): Number {
    return Number(data.replace(',', '.'));
  }

  deserialize(data: Number): String {
    return undefined;
  }

}

Each converter must implement CustomConverter interface and must have two methods:

The serialize method takes the ClassName value of the property and returns the transformed value.

N.B.: The converter can be defined also on an array, and an object type property. \ In this case, the same converter is applied on each element/property of the array/object that doesn't have its own converter.

deepFind

Given an object, returns the value of the property at a specific path.

 const obj = new ClassName();
...
 CmUtilsService.deepFind(obj, 'path.to.key')

N.B.: the path must start from the root of the object and each level must be separated by a dot. \ For arrays, the key is the index of the element.

deepUpdate

Given an object, update the value of the property at a specific path.

 const obj = new ClassName();
...
 CmUtilsService.deepUpdate(obj, 'path.to.key', newValue)

N.B.: the path must start from the root of the object and each level must be separated by a dot. \ For arrays, the key is the index of the element.

deepRemove

Given an object, remove the property at a specific path.

 const obj = new ClassName();
...
 CmUtilsService.deepRemove(obj, 'path.to.key')

N.B.: the path must start from the root of the object and each level must be separated by a dot. \ For arrays, the key is the index of the element.

Pipes

The library also provides the following pipes:

  • isUndefined: check if element is undefined
  • isNull: check if element is null
  • isNil: check if element is null or undefined
  • isEmpty: check if element is empty
  • isNilty: check if element is null or undefined or empty

Authors

  • Andrea Cimini

License

This project is licensed under the Apache License 2.0 - see the LICENSE.md file for details.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文