_primary

原子模块

底层原子类操作,该操作通常不带有任何业务信息,为底层的基础操作,模块内的API不带任何函数前缀,仅为通用函数,此处先列举所有API的相关说明:

函数名 说明
assign Object.assign则增强版,支持三种模式:常用模式、覆盖模式、追加模式,内置对象执行递归嵌套。
clone 深度拷贝对象,不同模式对象实现不同的拷贝,拷贝对象最终使用===方式会检测为false。
debug 「开发」调试专用函数。
denull 去空API,将Object中的field = null的键值对移除掉。
element 读取对应id的HTML元素,等价document.getElementById
fn 「综合」上层函数调用专用方法。
getV 「引擎」读取reference的state或props中对应键值下的数据。
immutable 标准函数,用于构造Immutable中的List/Map对象,调用高层API专用。
initial 「引擎」不同表单模式中计算初始值的专用函数。
input 执行带有mapping的正向转换。
merge 双合并函数,Array和Object两个对象进行同时合并,Object内部合并仅执行Object.assign默认模式。
monad 函数式编程的Monad函数链执行,构造综合函数链。
output 执行带有mapping的逆向转换。
packet 「引擎」Promise中断专用函数。
parallel 并行Promise专用函数。
pass 「引擎」执行从props -> state过程中的综合合并流程。
passion 串行Promise专用函数。
pipe 「引擎」尾部函数,执行setState的最终方法。
prevent 调用event.preventDefault()的专用函数,针对<a/>特别有效。
promise 构造异步Promise的专用过程。
ready 「引擎」设置$ready的值为true,返回Promise。
sequence 序号生成专用函数,支持大写字母、小写字母、数字三种模式。
signature 「安全」数字签名专用函数。
slice 切片函数,针对Object/Array实现切片,生成子元素。
token 「安全」读取当前用户的token信息。

Methods

(static) assign(target, source, mode) → {Object}

「标准」Ux.assign

三种模式的拷贝函数,增强原始的Object.assign函数。

  • mode = 0 :直接覆盖,内部调用Object.assign方法。
  • mode = 1 :深度覆盖,不直接覆盖子对象,递归往下,发现同键数据后直接覆盖数据。
  • mode = 2 :深度追加,不直接覆盖子对象,递归往下,同键不存在则追加,出现重复建则直接跳过。
// mode = 0(默认模式)
const target = {
    name: "mode"
};
const source = {
    email: "lang.yu@hpe.com"
};

// 等价于 Object.assign(target,source);
const combine = Ux.assign(target,source);

// mode = 1 和 mode = 2 的模式则参考实际使用。

实际上mode为1或2的场景在很多实战场景中有所使用,这两种模式不会直接覆盖子对象(包括嵌套对象),而是通过比对的方式执行覆盖追加(同名跳过)操作,实现深度合并。

Parameters:
Name Type Default Description
target Object

拷贝目标(副作用修改)

source Object

拷贝源

mode Number 0

模式参数,用于不同的模式:0 = 默认,1 = 深度覆盖,2 = 深度追加

Returns:

合并好的JavaScript对象Object

Type
Object

(static) clone(input) → {any}

「标准」Ux.clone

该函数是一个高频使用函数,内置使用Immutable的API实现对象拷贝,拷贝对象分为以下几种场景:

  1. 普通JS对象:Object/Array,直接调用Immutable.fromJS.toJS的链式调用实现对象拷贝。
  2. DataArray/DataObject:将这两种对象的内部内容拷贝出来,生成Object或Array。
  3. Function:(不拷贝),直接返回原始函数,防止函数拷贝过程中的错误信息。
  4. NodeList:Dom对象由于挂载在HTML元素中,所以不执行拷贝,而是直接返回该Dom引用。
  5. Set:如果是集合,则创建一个新的集合,将元素依次追加到集合中。
  6. Acl数组:对存在权限控制的Array/Object而言,它会包含一个索引之外的__acl属性,该属性存储了Acl的权限属性。
    1. 对Object类型而言,会直接拷贝__acl属性。
    2. 对Array类型,需要独立拷贝__acl属性(Immutable不会复制非索引访问的属性)。

此处的JS应用了原型链,由于Array本身是一个Object,所以除了索引以外,可直接追加属性,只是这些属性不作为标准Array元素对待。

// 直接拷贝对象,拷贝过后的对象的任何更改都不会反应到原始对象
const before = {
     name: "Lang"
};
const after = Ux.clone(before);
after.name = "Lang2";
console.info(item,input);

// before 的值依旧是:{ name: "Lang" }
// after 的值为修改后的值 { name: "Lang2" };
Parameters:
Name Type Description
input DataObject | DataArray | Object | Array

传入合法对象,

Returns:

返回拷贝好的 Object

Type
any

(async, static) debug(argumentsopt) → {Promise.<T>}

「开发专用」Ux.debug

输入可变长度的参数执行调试专用

  1. 长度为1:根据参数长度判断当前信息如何处理
    1. Object参数,直接返回这个Object的完成信息生成Promise
    2. String参数,返回Function函数,从函数参数中提取 field = String的键值

// 该方法仅在 "开发环境" 中使用,其他地方无法使用
const user = {
    username: "Lang",
    email: "lang.yu@hpe.com"
}
return Ux.promise(user)

     // 直接打印整个 user 对象的信息
     .then(Ux.debug)

     // 仅打印 user 对象的 email 字段
     .then(Ux.debug("email"));
Parameters:
Name Type Attributes Description
arguments arguments <optional>

可变长度参数

Returns:

返回一个Promise

Type
Promise.<T>

(static) denull(data) → {Object}

「标准」Ux.denull

针对传入的Object类型执行去空操作,删除掉数据中 field = null 的属性键值对。

执行前

{
    "username": "Lang",
    "password": "pl,okmijn123",
    "email": null
}

执行后

{
    "username": "Lang",
    "password": "pl,okmijn123"
}

由于Array类型可直接在 filter 方法中直接处理,所以不需要特殊的 denull 方法来执行过滤,而Object没有该方法过滤,所以提供该API。

Parameters:
Name Type Description
data Object

输入的对象信息

Returns:

返回处理过后的对象原始引用

Type
Object

(static) element(id) → {HTMLElement}

「标准」Ux.element

等价于 document.getElementById 读取HTML元素。

Parameters:
Name Type Description
id String

HTML元素的ID值

Returns:
Type
HTMLElement

(static) fn(reference) → {function}

「标准」Ux.fn

Ux.fn(reference).xxx 方式调用函数,使用reference 构造对应的函数信息,需要注意的是: 除了onChange/onSelect以外,其他所有函数都是以rx开始,rx在Zero Ui中的全称是:Reactive X,最初设计这种函数名的目的是区分 不同的函数前缀,其中包括:

前缀 说明
on HTML和Ant Design原生事件函数。
rx 自定义函数,Reactive X定义,Zero Ui专用函数。
fn 自定义纯函数,JavaScript Function对应的定义。
ix 「保留」内置专用函数,Internal X定义,Zero Ui保留的专用函数。

1. 函数检索规则

  1. 先从reference的state中读取对应函数,状态中的函数优先,和数据相反,状态中的函数有可能是在componentDidMount中定义的。
  2. 再从reference的props中读取函数。
  3. 如果都无法读取时则报错,该函数最终会返回函数引用。

2. 函数支持表

函数名 说明
onChange 原生HTML(包括AntD)常用的onChange方法。
onSelect 原生HTML(包括AntD)常用的onSelect方法。
rxSource 读取数据源的专用方法,组件中特定数据源的读取。
rxSubmit 提交函数。
rxClose 关闭函数。
rxFilter 过滤函数。
rxSelect 选择函数。
rxTree 树操作函数。
rxChild 绑定子组件专用函数。
rxCheck 选择函数,Checkbox专用。
rxClean 清除函数,清除选中状态专用。
rxDropOver 拖拽时触发的悬停覆盖函数。
rxBack 返回函数。
rxJumpPage 跳页函数。
rxNext 下一步函数。
rxNextPage 下一页函数。
rxPrev 上一步函数。
rxPrevPage 上一页函数。
rxFirst 第一步函数。
rxFirstPage 第一页函数。
rxLast 最后一步函数。
rxLastPage 最后一页函数。
rxAdd 添加函数。
rxEdit 编辑函数。
rxDelete 删除函数。
rxRefresh 更新函数。
rxItemAdd 子项添加函数。
rxItemEdit 子项编辑函数。
rxItemDelete 子项删除函数。

3. 编辑器函数支持表

函数名 说明
rxRowAdd 行添加函数。
rxRowDel 行删除函数。
rxRowFill 行扩展函数。
rxRowCompress 行压缩函数。
rxRowWrap 行交换函数。
rxRowConfig 行配置函数,写入顶层raft。
rxCellAdd 单元格添加函数。
rxCellMerge 单元格合并函数。
rxCellDel 单元格删除函数。
rxCellSplit 单元格拆分函数。
rxCellFill 单元格填充函数。
rxCellWrap 单元格交换函数。
rxCellConfig 单元格配置函数。
rxCellRefresh 单元格刷新函数。

rx系列函数是Zero Ui中的最终标准!!!

Parameters:
Name Type Description
reference reference

传入部分的数据

Returns:

返回生成的最终函数

Type
function

(static) getV(reference, key) → {any}

「引擎」Ux.getV

从reference的state和props中分批读取数据

  1. 先从reference.state中读取数据。
  2. 如果第一步失败,则从reference.props中读取数据。

此处说明一下读取数据的优先级问题,根据目前实战的情况看起来,先从state中读取,再从props中读取的流程存在于多个组件中 并不是空穴来风的设计,所以存在这种读取方式,不仅仅是denull的API,包括很多读取函数以及后续的API都有该操作流程。

Parameters:
Name Type Description
reference ReactComponent

某个React组件的引用

key String

读取状态和属性值时传入的属性名

Returns:

返回最终数据。

Type
any

(static) immutable(input) → {Map|List}

「标准」Ux.immutable

直接调用 immutable 包中的 Immutable.fromJS 函数,生成 Immutable 对象,该对象包含了很多新的API,如常用的:

  • getIn:可直接使用getIn(["field1","field11"])读取嵌套属性。
  • setIn:可使用setIn(["field1","field11"])设置嵌套属性。
  • contains:高频使用方法,特别是Array模式,当然也可以直接使用ES6中的Set.has来判断。
const item = ["key", "key1"];
const $item = Ux.immutable(item);

console.info($item.contains("key"));
Parameters:
Name Type Description
input Object | Array

输入对象,可以是任意 JavaScript 对象

Returns:

Immutable库中需要使用的专用对象

Type
Map | List

(static) initial(reference, form, program) → {Object}

「引擎」Ux.initial

执行表单初始化逻辑,实现表单属性$inited的完整计算流程,不论是静态配置还是动态配置,都生效,表单初始化流程如下:

  1. 添加模式中(mode = ADD):判断form中是否包含了initial属性,如果包含了initial属性,则使用initial属性计算。
    • 此时initial中的属性对应值支持表达式如UNIQUE:xxx这种,所有在表单中可支持的表达式都可执行初始化计算,计算源以reference为主。
  2. 编辑模式中(mode = EDIT):编辑模式直接将$inited变量的值赋值到初始化数据中。

第三参数program主要负责提供编程模式的覆盖参数,它的优先级最高,如果出现了同名属性,直接用program中的函数进行覆盖。

Parameters:
Name Type Description
reference ReactComponent

React对应组件引用。

form Object

表单配置。

program Object

编程专用的配置数据传入。

Returns:

初始化数据(表单初始化数据)。

Type
Object

(static) input(params, mapping) → {Object}

「标准」Ux.input

数据转换专用函数,params -> mapping -> request的流程,此处request为转换后的函数。

如:

数据文件 params:

{
    "username": "Lang",
    "email": "lang.yu@hpe.com"
}

配置文件 mapping:

{
    "username": "account"
}

转换过后的输出信息为:

{
    "account": "Lang",
    "email": "lang.yu@hpe.com"
}

从转换流程可以知道,这个配置的转换流程是正向转换,执行前端映射。

Parameters:
Name Type Description
params Object

输入的对象信息

mapping Object

传入更改对象的映射的

Returns:

返回执行过后的结果。

Type
Object

(static) merge(original, newValue, field) → {Array|Object}

「标准」Ux.merge

执行Array和Object的双合并方法,生成合并过后的新对象专用,注意此处的Array必须是Object对象数组,且第三参在Array中生效。

  1. 如果传入类型是Object:
    1. 如果original有值,则使用Object.assign生成新对象,既不改变原始的,也不改变新的。
    2. 如果original无值,则拷贝一个newValue新对象。
  2. 如果传入类型是Array:
    1. 如果original有值并且0 < length,则根据第三参field来执行合并操作,内部调用elementUnique专用方法。
    2. 如果newValue是数组,并且original长度为零或无值,则直接拷贝newValue。

这个函数没有任何副作用,既不改变原始的original,也不改变newValue,为一个无副作用函数,最终返回的数据是拷贝的副本。

Parameters:
Name Type Default Description
original Array | Object

原始数据结构

newValue Array | Object

更新后的数据结构

field String key

如果是数组则按field合并

Returns:

返回合并后的值

Type
Array | Object

(static) monad(funArray) → {function}

「标准」Ux.monad

Monad 生成器,用于生成多维函数链,它的执行流程如下:

  1. input输入
  2. funArray[0]执行:input -> ret0
  3. funArray[1]执行:ret0 ( input1 ) -> ret1
  4. funArray[2]执行:ret1 ( input2 ) -> ret2 .....

传入的funArray中的每一个元素都是Function类型,如果不是Function类型则直接跳过不执行,最终会生成一个搭载了 函数链的综合函数,用于执行Monad专用函数链。

input -> funArray[0] -> funArray[1] -> funArray[2] -> .... -> output

该API用于函数式编程,只支持同步模式,异步模式目前不支持。

Parameters:
Name Type Description
funArray Array

传入的可绑定函数数组,每个元素都是一个 Function

Returns:
Type
function

(static) output(params, mapping) → {Object}

「标准」Ux.output

这个函数是Ux.input的逆向操作函数,会执行mapping配置中的逆向转换,通常是处理响应用response -> mapping -> params

Parameters:
Name Type Description
params Object

输入的对象信息

mapping Object

传入更改对象的映射的

Returns:

返回执行过后的结果。

Type
Object

(async, static) packet(promise) → {Promise.<T>|Object}

「标准」Ux.packet

包装过的 Promise,解决内存Bug,中途 Cancel,如果出现异常则执行中断处理,该中断处理可解决当出现异步异常时的基本 流程,通过中断也可以实现Bug的处理。

Parameters:
Name Type Description
promise Promise.<T>

传入一个合法的Promise。

Returns:

返回Promise或同步结果。

Type
Promise.<T> | Object

(static) parallel(promises, …keys) → {Promise.<T>}

「标准」Ux.parallel

并行 Promise 专用函数,每个 Promise 会同时执行最终合并结果,直接构造并行运行结果

  1. 如果不传第二参数,keys 长度为 0,则直接返回 [x] 的 promises 直接结果
  2. 如果传入第二参,keys 长度 > 0,则会返回 {} 的 promises 直接结果

直接并行 []

const promiseArray = [
     promise1,       // 假设返回 {name:"Lang"}
     promise2,       // 假设返回 [1,2]
     promise3        // 假设返回 "3 Promise"
];
Ux.parallel(promiseArray).then(response => {
     // response 数据结构:
     // [
     //      {name, "Lang"},
     //      [1,2],
     //      "3 Promise"
     // ]
});

异构并行 {}

const promiseArray = [
     promise1,       // 假设返回 {name:"Lang"}
     promise2,       // 假设返回 [1,2]
     promise3        // 假设返回 "3 Promise"
];
Ux.parallel(promiseArray, "user", "number").then(response => {
     // response 数据结构:
     // {
     //      "user": {name, "Lang"},
     //      "number": [1,2],
     //      "2": "3 Promise"
     // }
});
Parameters:
Name Type Attributes Description
promises Array

一个 Promise 的数组。

keys Array.<String> <repeatable>

一个包含键的数组,用于处理最终返回值专用。

Returns:

返回最终的 Promise

Type
Promise.<T>

(static) pass(reference, field) → {Object}

「引擎」Ux.pass

根据传入的field值同时从reference中提取数据,提取结果通常是Object,然后执行合并

  1. props中的同名属性值会覆盖state中的同名属性值。
  2. 最终合并过程不会修改输入:
    1. 如果是props本身是只读,不能变更。
    2. 如果是state更改只能使用setState,不可直接变更。

该函数会执行combine的合并操作,合并操作会实现对象的提取,带有子对象处理功能。

Parameters:
Name Type Description
reference ReactComponent

React组件引用

field String

提取数据的属性值

Returns:

返回合并过后的对象信息

Type
Object

(async, static) passion(generator, input) → {Promise.<T>}

「标准」Ux.passion

顺序链接 Promise 专用函数(串行Promise),最终构造成 Monad 链

input -> Monad1 -> out1,
out1 ->  Monad2 -> out2,
out2 ->  Monad3 -> out3,
....

# 最终构造链式结构
Monad1 -> Monad2 -> Monad3 -> ... -> Monadn

执行步骤如下:

  1. 数组中的每一个元素都必须是一个函数生成器(generator),每调用一次会生成这个节点的 Promise
  2. 使用 generator 的目的是保证每个 Promise 都是延迟生成。
  3. 按照流程,第一个 generator 生成了 Promise 过后,会使用 then 的方式继续往下直到最后一个执行完成。
Parameters:
Name Type Description
generator Array

构造每一个节点的 Promise 的专用函数

input any

第一个节点的 Promise 的输入参数

Returns:

返回最终的 Promise 信息

Type
Promise.<T>

(async, static) pipe(argumentsopt) → {Promise.<T>}

「引擎」Ux.pipe

输入可变长度参数相关信息,暂时支持:

  1. 长度为1:必须输入 reference(React中的Component)

该方法主要位于 then 的函数链执行,执行过后会更新 React 组件中的状态,该方法有一定的副作用,因为它会执行一次setState, 所以真正使用这个函数时通常放在整个链式结构的尾部,而尾部执行操作可让系统处于最终的加载完成的状态。

【巧】技巧代码

旧代码


const reference = "从外置传入的 reference ";
Ux.ajaxGet("/api/pipe").then(state => {
    reference.setState(state);
    return Ux.promise(state);
});

新代码


// 使用 pipe 过后的改动代码
const reference = "从外置传入的 reference ";
Ux.ajaxGet("/api/pipe").then(Ux.pipe(reference));

Parameters:
Name Type Attributes Description
arguments arguments <optional>

可变长度参数

Returns:

返回一个Promise

Type
Promise.<T>

(static) prevent(event) → {Object}

「标准」Ux.prevent

特殊二义性函数「Ambiguity」,该函数的输入会有两种类型,其实第一种方式应用特别多:

  • 如果传入的是HTML中的native本地函数,通常在Button的onClick中会被传入。
  • 如果传入的是Object数据,那么直接返回该Object数据。

这个函数读取数据有另外的一个API来实现ambEvent,所以这里只是为了执行单纯的方法,它执行的核心代码为event.preventDefault()

     // 绑定事件
     const onClick = (event) => {
         Ux.prevent(event);
     }
     // 直接传入参数
     const onForm = (params = {}) => {
         const request = Ux.prevent(params);
     }
Parameters:
Name Type Description
event Event | Object

传入事件或对象

Returns:

返回对象信息

Type
Object

(async, static) promise(argumentsopt) → {Promise.<T>}

「标准」Ux.promise

多义性方法,用于返回不同结果的 Promise,多用于函数链中,该方法只对 1,2,3 的长度有效, 不在这个长度范围内时会直接返回 Promise.reject 的异常信息。

  1. 长度为1,直接返回new Promise,将传入对象封装成 Promise 返回,同步转异步。
  2. 长度为2,使用 Supplier 和第二参直接生成 Promise 返回(延迟异步,同步转异步)。
  3. 长度为3,一般用于 Monad 函数链,通常在状态迁移中处理。

长度1

const user = {
    username: "Lang Yu"
};
const promise = Ux.promise(user);

长度2

const supplier = (params = {}) => {

     // 构造新的 Promise
     return Ux.ajaxGet("/api/test/:key", params);
};
const promise = Ux.promise(supplier, {key:"user.id"});

长度3

【巧】技巧代码

旧代码


const state = {};
Ux.ajaxGet("/api/test").then(response => {
    state.$data = response;
    return Ux.promise(state);
})

新代码

const state = {};
Ux.ajaxGet("/api/test")
     .then(response => Ux.promise(state, "$data", response));

该API提供的方法在整个Promise链中为高频使用方法,他的使用场景有很多,主要是用于修正代码编写风格,使用场景如下:

  1. 直接将一个对象Object/Array等转换成带有异步Promise的数据结构,可直接调用.then的API。
  2. 长度2的使用场景主要用于切面AOP的编程,通常在很多场景中需要执行多维度构造,特别是中间维度的Promise的构造过程。
  3. 长度3的使用场景则通常用于componentDidMount的生命周期中,用于实现挂载流程,如response -> state[key] = response的结构。

该方法存在的意义在于封装了ES6中出现的Promise流程,方便整体调用,Zero Ui的理念是封装第三方,那么第三方的内容封装越多,开发人 员对本身框架的操作程度会越过,其实第一种应用是最常用的,其次是配置化流程中通常使用第二和第三种流程。

Parameters:
Name Type Attributes Description
arguments arguments <optional>

可变长度参数

Returns:

返回最终的 Promise

Type
Promise.<T>

(async, static) ready(state) → {Promise.<T>}

「引擎」Ux.ready

在 Zero Extension 中,内置了配置准备状态,state 中的 $ready,当界面 componentDidMount 执行完成后 会将 $ready 设置成 true,该函数几乎是整个Zero Ui的核心,主要用于设置生命周期的完整。

  1. $ready = false:等待配置完成。
  2. $ready = true:配置执行完成,执行过程可以是异步

旧代码

const key = "1";

Ux.ajaxGet("/api/user",key).then(state => {
     state.$ready = true;
     return Ux.promise(state);
});

新代码

// 使用 ready 过后的改动代码
const key = "1";

Ux.ajaxGet("/api/user",key).then(Ux.ready);

该方法只能作为Monad的中间节点,不可用于尾部节点或开始节点,只能处于函数链的中间环节,Zero中常用的一段代码如:

// 下边代码是常用代码,可设置 $ready = true 来实现准备完成
<Promise>.then(Ux.ready).then(Ux.pipe(this));

在React组件的生命周期中,componentDidMount会执行Ajax的异步操作,到最后设置$ready=true的标识来表示回调 完成,而这种回调完成刚好可应用于当前组件,也就是说当$ready=true时,状态加载彻底完成。

Parameters:
Name Type Description
state

处理之前的原始状态信息,函数链上的 Monad

Returns:

返回一个新的 Promise

Type
Promise.<T>

(static) sequence(input, mode) → {String|Number}

「标准」Ux.sequence

序号生成函数,根据输入生成相关序号信息,第二参支持的模式如下:

  1. DIGEST:数字序号:1,2,3,4
  2. UPPER:大写字母序号:A,B,C,D 等
  3. LOWER:小写字母序号:a,b,c,d 等

如数参数input必须是数值,如果不是数值则直接报错,该函数会返回对应序号中的值。

Parameters:
Name Type Default Description
input Number

输入的序号,序号从 1 开始

mode String DIGEST

当前生成序号的模式,支持三种模式

Returns:

生成的序号信息

Type
String | Number

(static) signature(uri, method, params)

##「标准」Ux.signature

Zero UI中的RESTful 数字签名功能专用函数。

Parameters:
Name Type Default Description
uri String

待签名的路径信息。

method String GET

待签名的方法信息。

params Object

待签名的方法参数。

(static) slice(input, …keys) → {Object}

「标准」Ux.slice

切片函数,针对对象或数组直接执行切片操作,生成新的子元素(可以是Object,也可以是Array)。

Object 类型

const before = {
    a: "a", b:"b", c:"c"
}
const after = Ux.slice(before, "a", "b");
// after 的最终值是:{ a:"a", b:"b" }

Array 类型

const before = [
     { a: "a1",  b: "b1", c: "c1" }.
     { a: "a2",  b: "b2", c: "c2" }.
]
const after = Ux.slice(before, "b", "c");
// after 的最终结果是:
// [
//      { b:"b1", c:"c1" },
//      { b:"b2", c:"c2" }
// ]
Parameters:
Name Type Attributes Description
input Array | Object

输入可以是对象,可以是数组

keys Array.<String> <repeatable>

可变参数,每个元素都是字符串

Returns:

返回子集对象

Type
Object

(static) token() → {String}

##「标准」Ux.token

返回安全请求中的令牌信息,最终会根据应用模式处理成 Authorization 的计算值。

Returns:

返回当前用户登录过后的令牌token信息。

Type
String