kn-hooks 0.0.39 → 0.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module useDictionary
|
|
3
|
+
*/
|
|
4
|
+
import React,{ useState, useMemo, useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @template [T=object]
|
|
9
|
+
* @callback Api
|
|
10
|
+
* @param {Object} params - 调用接口用到的参数
|
|
11
|
+
* @returns {Promise<T>}
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef DictionaryItem
|
|
17
|
+
* 字典数据的结构
|
|
18
|
+
* @property {string} id - 数据唯一ID
|
|
19
|
+
* @property {string} name - 数据唯一id对应的别名
|
|
20
|
+
* @property {string} label - 展示给用户看的文字
|
|
21
|
+
* @property {boolean} [disabled] - 是否禁用
|
|
22
|
+
* @property {object} [data] - 原始数据
|
|
23
|
+
* @property {string} [subLabel] - 副标题
|
|
24
|
+
* @property {string} [type] - 是不是多选框
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @typedef CreateOptions
|
|
30
|
+
* @property {DictionaryItem[]} types - 字典数据列表
|
|
31
|
+
* @property {string} [idKey='id'] - id的字段名
|
|
32
|
+
* @property {string} [nameKey='name'] - id的字段名
|
|
33
|
+
* @property {string} [labelKey='label'] - id的字段名
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @typedef GetOptionsProps
|
|
39
|
+
* @property {object} props
|
|
40
|
+
* @property {(item:DictionaryItem)=>boolean} [props.onFilter] - 数据唯一id对应的别名
|
|
41
|
+
* @property {(item:DictionaryItem)=>boolean} [props.onDisabled] - 数据唯一id对应的别名
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef RenderOptionsProps
|
|
46
|
+
* @property {object} props
|
|
47
|
+
* @property {DictionaryItem[]} [props.options] - 数据唯一id对应的别名
|
|
48
|
+
* @property {JSX.Element} [props.OptionComponent] - 数据唯一id对应的别名
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @typedef RenderOptions
|
|
54
|
+
* @property {(item:DictionaryItem)=>ReactDOM} onRender - 渲染拦截器
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @typedef EnumResult
|
|
59
|
+
* @property {DictionaryItem[]} types - 字典数据列表
|
|
60
|
+
* @property {(labelOrName:string)=>string} getId - 搜索字典项中,label或name匹配labelOrName的项目,返回其id的值
|
|
61
|
+
* @property {(id:string)=>string} getName - 匹配id复合的对象,返回其name的值
|
|
62
|
+
* @property {(id:string)=>string} getLabel - 匹配id复合的对象,返回其label的值
|
|
63
|
+
* @property {(idOrNameOrLabel:string)=>DictionaryItem} getItem - 匹配id,label,name只要符合的返回对象
|
|
64
|
+
* @property {(props?:GetOptionsProps)=>DictionaryItem[]} getOptions - 获取选项列表
|
|
65
|
+
* @property {(props?:RenderOptions)=>ReactDOM[]} render - 触发渲染
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @typedef CreateApiDictionaryOptions
|
|
72
|
+
* @property {Api} [api] - 用于获取字典列表的接口
|
|
73
|
+
* @property {(request:object)=>object} [beforeApi] - (request:object)=>object 接口调用前的参数拦截器
|
|
74
|
+
* @property {(response:object)=>object} [afterApi] - (reponse:object)=>object[] 接口调用后的拦截器
|
|
75
|
+
* @property {DictionaryItem[]} [defaultTypes] - 如果字典不是通过api获取,可以在这里设置字典的内容
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* @typedef {CreateOptions & CreateApiDictionaryOptions} CreateDictionaryOptions
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @typedef CreateDictoryResult
|
|
84
|
+
* @property {()=>boolean} isReady - 是否加载完毕
|
|
85
|
+
* @property {()=>void} reload - 重新加载
|
|
86
|
+
*
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* @typedef {CreateDictoryResult & EnumResult} UseDictionaryResult
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
const DEFAULT_CONFIG={
|
|
95
|
+
beforeApi:null,
|
|
96
|
+
afterApi:null,
|
|
97
|
+
idKey:'id',
|
|
98
|
+
nameKey:'name',
|
|
99
|
+
labelKey:'label'
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @function
|
|
105
|
+
* @description 全局设置SelectOption和RadioOption
|
|
106
|
+
* @param {Object} params
|
|
107
|
+
*
|
|
108
|
+
* @returns {void}
|
|
109
|
+
*/
|
|
110
|
+
export const SetConfig = ({beforeApi,afterApi,idKey,nameKey,labelKey})=>{
|
|
111
|
+
if(beforeApi)DEFAULT_CONFIG.beforeApi = beforeApi;
|
|
112
|
+
if(afterApi)DEFAULT_CONFIG.afterApi = afterApi;
|
|
113
|
+
if(idKey)DEFAULT_CONFIG.idKey = idKey;
|
|
114
|
+
if(nameKey)DEFAULT_CONFIG.nameKey = nameKey;
|
|
115
|
+
if(labelKey)DEFAULT_CONFIG.labelKey = labelKey;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* 创建一个静态的字典
|
|
121
|
+
* @param {CreateOptions} props
|
|
122
|
+
* @returns {EnumResult}
|
|
123
|
+
*/
|
|
124
|
+
export const createEnum=props=>{
|
|
125
|
+
const {
|
|
126
|
+
idKey = DEFAULT_CONFIG.idKey,
|
|
127
|
+
nameKey = DEFAULT_CONFIG.nameKey,
|
|
128
|
+
labelKey = DEFAULT_CONFIG.labelKey,
|
|
129
|
+
types,
|
|
130
|
+
} = props;
|
|
131
|
+
|
|
132
|
+
const idMap={};
|
|
133
|
+
const labelMap={};
|
|
134
|
+
const nameMap={};
|
|
135
|
+
|
|
136
|
+
if(types){
|
|
137
|
+
types.forEach(item=>{
|
|
138
|
+
idMap[''+item[idKey]] = item;
|
|
139
|
+
labelMap[''+item[labelKey]] = item;
|
|
140
|
+
nameMap[''+item[nameKey]] = item;
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const getLabel = (id) => {
|
|
145
|
+
let key = ''+id;
|
|
146
|
+
if(!types)return '';
|
|
147
|
+
if(idMap[key]){
|
|
148
|
+
return idMap[key][labelKey]
|
|
149
|
+
}
|
|
150
|
+
return '';
|
|
151
|
+
};
|
|
152
|
+
const getName = (id) => {
|
|
153
|
+
let key = ''+id;
|
|
154
|
+
if(!types)return '';
|
|
155
|
+
if(idMap[key]){
|
|
156
|
+
return idMap[key][nameKey]
|
|
157
|
+
}
|
|
158
|
+
return '';
|
|
159
|
+
};
|
|
160
|
+
const getId = (labelOrName) => {
|
|
161
|
+
let key = ''+labelOrName;
|
|
162
|
+
if(!types)return '';
|
|
163
|
+
if(nameMap[key]){
|
|
164
|
+
return nameMap[key][idKey]
|
|
165
|
+
}
|
|
166
|
+
if(labelMap[key]){
|
|
167
|
+
return labelMap[key][idKey]
|
|
168
|
+
}
|
|
169
|
+
return '';
|
|
170
|
+
};
|
|
171
|
+
const getItem=(idOrNameOrLabel)=>{
|
|
172
|
+
let key = ''+idOrNameOrLabel;
|
|
173
|
+
if(!types)return null;
|
|
174
|
+
if(idMap[key]){
|
|
175
|
+
return idMap[key]
|
|
176
|
+
}
|
|
177
|
+
if(nameMap[key]){
|
|
178
|
+
return nameMap[key]
|
|
179
|
+
}
|
|
180
|
+
if(labelMap[key]){
|
|
181
|
+
return labelMap[key]
|
|
182
|
+
}
|
|
183
|
+
return null;
|
|
184
|
+
};
|
|
185
|
+
const getOptions=(props)=>{
|
|
186
|
+
const {onFilter,onDisabled}=props;
|
|
187
|
+
let req=[];
|
|
188
|
+
if(!types)return req;
|
|
189
|
+
types.forEach(item=>{
|
|
190
|
+
let show=true;
|
|
191
|
+
let disabled=false;
|
|
192
|
+
|
|
193
|
+
if(onFilter){
|
|
194
|
+
show = onFilter(item);
|
|
195
|
+
}
|
|
196
|
+
if(onDisabled){
|
|
197
|
+
disabled = onDisabled(item);
|
|
198
|
+
}
|
|
199
|
+
if(show){
|
|
200
|
+
req.push({
|
|
201
|
+
...item,
|
|
202
|
+
disabled:disabled,
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
return req;
|
|
207
|
+
}
|
|
208
|
+
const render=(props)=>{
|
|
209
|
+
const {onRender} = props;
|
|
210
|
+
let req=[];
|
|
211
|
+
if(!onRender)return req;
|
|
212
|
+
types.forEach(item=>{
|
|
213
|
+
if(onRender){
|
|
214
|
+
let component=onRender(item);
|
|
215
|
+
if(component){
|
|
216
|
+
req.push(component);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
})
|
|
220
|
+
return req;
|
|
221
|
+
}
|
|
222
|
+
return { types, getLabel, getId, getName,getItem,getOptions,render };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @function
|
|
228
|
+
* @description 创建字典hooks工具
|
|
229
|
+
* @param {CreateDictionaryOptions} options
|
|
230
|
+
*
|
|
231
|
+
* @returns {()=>UseDictionaryResult}
|
|
232
|
+
*/
|
|
233
|
+
export const createDictionary=options=>{
|
|
234
|
+
const {
|
|
235
|
+
api,
|
|
236
|
+
beforeApi = DEFAULT_CONFIG.beforeApi,
|
|
237
|
+
afterApi = DEFAULT_CONFIG.afterApi,
|
|
238
|
+
} = options;
|
|
239
|
+
const defaultTypes = options.defaultTypes || options.types || null;
|
|
240
|
+
return ()=>{
|
|
241
|
+
/**
|
|
242
|
+
* @type {[EnumResult,React.Dispatch<EnumResult>]}
|
|
243
|
+
*/
|
|
244
|
+
const [enumItem, setEnumItem] = useState(()=>{
|
|
245
|
+
if(!api)return createEnum({...options,types:defaultTypes||[]})
|
|
246
|
+
return {types:null}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const init = async () => {
|
|
250
|
+
if(!api)return;
|
|
251
|
+
let params={};
|
|
252
|
+
let items=[];
|
|
253
|
+
if(beforeApi){
|
|
254
|
+
params = beforeApi();
|
|
255
|
+
}
|
|
256
|
+
let ret = await api(params);
|
|
257
|
+
if(afterApi){
|
|
258
|
+
items = afterApi(ret);
|
|
259
|
+
}else{
|
|
260
|
+
if (+ret?.code === 0) {
|
|
261
|
+
items = ret.data.body;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let value=createEnum({...options,types:items||[]});
|
|
265
|
+
setEnumItem(value);
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const isReady = () => {
|
|
269
|
+
return enumItem?.types !== null;
|
|
270
|
+
};
|
|
271
|
+
const reload = () => {
|
|
272
|
+
init();
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
init();
|
|
277
|
+
}, [api,beforeApi,afterApi]);
|
|
278
|
+
|
|
279
|
+
const actions = useMemo(() => {
|
|
280
|
+
return { isReady, reload,...enumItem };
|
|
281
|
+
}, [enumItem]);
|
|
282
|
+
|
|
283
|
+
return actions;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
useDictionary.createDictionary=createDictionary;
|
|
291
|
+
useDictionary.SetConfig = SetConfig;
|
|
292
|
+
|
|
293
|
+
export default useDictionary
|
|
@@ -11,8 +11,14 @@ import useSwitch from '../useSwitch';
|
|
|
11
11
|
* @property {Pagination} [pagination] - 默认分页信息
|
|
12
12
|
* @property {Array<Function>} [beforeService] - api调用前监听方法列表
|
|
13
13
|
* @property {Array<Function>} [afterService] - api调用后监听方法列表
|
|
14
|
+
* @property {string} [mode='pagination'] - pagination普通分页形式, scrollLoad 滚动加载,取值来源usePagination.MODE
|
|
15
|
+
* @property {boolean} [debug=false] - 是否进入调试模式
|
|
14
16
|
*/
|
|
15
17
|
|
|
18
|
+
const MODE={
|
|
19
|
+
pagination:'pagination',
|
|
20
|
+
scrollLoad:'scrollLoad',
|
|
21
|
+
}
|
|
16
22
|
/**
|
|
17
23
|
* 分页管理器
|
|
18
24
|
*
|
|
@@ -90,15 +96,17 @@ import useSwitch from '../useSwitch';
|
|
|
90
96
|
*/
|
|
91
97
|
const usePagination=(props)=>{
|
|
92
98
|
|
|
93
|
-
const {service}= props;
|
|
99
|
+
const {service,mode=MODE.pagination,debug=false}= props;
|
|
94
100
|
|
|
95
101
|
const DEFAULT_PAGE_SIZE=20;
|
|
96
102
|
const DEFAULT_PAGE_CURRENT=1;
|
|
97
103
|
const [pagination,setPagination] = useState({
|
|
98
104
|
current: DEFAULT_PAGE_CURRENT,
|
|
99
|
-
pageSize: props?.pagination?.pageSize??DEFAULT_PAGE_SIZE
|
|
105
|
+
pageSize: props?.pagination?.pageSize??DEFAULT_PAGE_SIZE,
|
|
100
106
|
});
|
|
101
107
|
const [data,setData] = useState(null);
|
|
108
|
+
const [scrollData,setScrollData] = useState(null);
|
|
109
|
+
|
|
102
110
|
const refListener= useRef({
|
|
103
111
|
beforeService:props?.beforeService??[],
|
|
104
112
|
afterService:props?.afterService??[]
|
|
@@ -111,13 +119,19 @@ const usePagination=(props)=>{
|
|
|
111
119
|
|
|
112
120
|
const {current,pageSize} = _pagination;
|
|
113
121
|
|
|
114
|
-
let params = {
|
|
122
|
+
let params = {pageSize};
|
|
123
|
+
if(mode==MODE.scrollLoad){
|
|
124
|
+
params.cursor = _pagination.cursor;
|
|
125
|
+
}else{
|
|
126
|
+
params.current= current;
|
|
127
|
+
}
|
|
128
|
+
|
|
115
129
|
let listener=refListener.current;
|
|
116
130
|
|
|
117
131
|
loading.open();
|
|
118
132
|
const {beforeService} = listener;
|
|
119
133
|
if(beforeService){
|
|
120
|
-
console.log('[usePagination] beforeService',params)
|
|
134
|
+
if(debug)console.log('[usePagination] beforeService',params)
|
|
121
135
|
for(let i=0;i<beforeService.length;i++){
|
|
122
136
|
params = beforeService[i](params);
|
|
123
137
|
if(typeof params?.then == 'function'){
|
|
@@ -130,11 +144,11 @@ const usePagination=(props)=>{
|
|
|
130
144
|
loading.close();
|
|
131
145
|
return;
|
|
132
146
|
}
|
|
133
|
-
console.log('[usePagination] service',params)
|
|
147
|
+
if(debug)console.log('[usePagination] service',params)
|
|
134
148
|
let req = await service(params);
|
|
135
149
|
const {afterService} = listener;
|
|
136
150
|
if(afterService){
|
|
137
|
-
console.log('[usePagination] afterService',req)
|
|
151
|
+
if(debug)console.log('[usePagination] afterService',req)
|
|
138
152
|
for(let i=0;i<afterService.length;i++){
|
|
139
153
|
req = afterService[i](req);
|
|
140
154
|
if( typeof req?.then == 'function' ){
|
|
@@ -142,36 +156,56 @@ const usePagination=(props)=>{
|
|
|
142
156
|
}
|
|
143
157
|
}
|
|
144
158
|
}
|
|
145
|
-
console.log('[usePagination] response',req)
|
|
159
|
+
if(debug)console.log('[usePagination] response',req)
|
|
146
160
|
let response={};
|
|
147
161
|
if(req?.code==0){
|
|
148
|
-
let {page:{current,total},data:reqData} = req;
|
|
162
|
+
let {page:{current=1,total=0,cursor=undefined},data:reqData} = req;
|
|
149
163
|
let _pageSize=pageSize;
|
|
150
164
|
// 兼容没数据的时候如果pageSize为0会导致接下来刷新的时候也按0的pageSize来写入
|
|
151
165
|
if(req?.page?.pageSize){
|
|
152
166
|
_pageSize=+req?.page?.pageSize;
|
|
153
167
|
}
|
|
154
|
-
current=+current;
|
|
155
168
|
total=+total;
|
|
156
|
-
|
|
157
|
-
|
|
169
|
+
let startIdx=0;
|
|
170
|
+
let more;
|
|
171
|
+
if(mode==MODE.pagination){
|
|
172
|
+
current=+current;
|
|
173
|
+
startIdx= (current-1)*_pageSize;
|
|
174
|
+
more = current*_pageSize<total;
|
|
175
|
+
}else{
|
|
176
|
+
more = req.page.more;
|
|
177
|
+
}
|
|
158
178
|
response.pagination={
|
|
159
|
-
current,pageSize:_pageSize,total,startIdx,more
|
|
179
|
+
current,pageSize:_pageSize,total,startIdx,more,cursor
|
|
160
180
|
};
|
|
161
181
|
setPagination(response.pagination);
|
|
162
|
-
response.data= clear?[]:(data||[]);
|
|
163
182
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
183
|
+
|
|
184
|
+
if(mode==MODE.pagination){
|
|
185
|
+
response.data= clear?[]:(data||[]);
|
|
186
|
+
if(response.data.length<current){
|
|
187
|
+
for(let i=0;i<current;i++){
|
|
188
|
+
response.data[i]=response.data[i]||[];
|
|
189
|
+
}
|
|
167
190
|
}
|
|
191
|
+
let pageIdx= current-1;
|
|
192
|
+
response.data[pageIdx]= response.data[pageIdx]||[];
|
|
193
|
+
response.data[pageIdx]= reqData||[];
|
|
194
|
+
response.data=[...response.data];
|
|
195
|
+
setData(response.data);
|
|
196
|
+
}
|
|
197
|
+
else if(mode==MODE.scrollLoad){// 滚动加载模式的数据组装
|
|
198
|
+
let _scrollData=clear?[]:(scrollData||[]);
|
|
199
|
+
_scrollData = [..._scrollData,...reqData];
|
|
200
|
+
// for(let data of response.data ){
|
|
201
|
+
// if(data!=null && Array.isArray(data) ){
|
|
202
|
+
// _scrollData = [..._scrollData,...data];
|
|
203
|
+
// }
|
|
204
|
+
// }
|
|
205
|
+
setScrollData(_scrollData)
|
|
168
206
|
}
|
|
169
|
-
let pageIdx= current-1;
|
|
170
|
-
response.data[pageIdx]= response.data[pageIdx]||[];
|
|
171
|
-
response.data[pageIdx]= reqData||[];
|
|
172
|
-
response.data=[...response.data];
|
|
173
|
-
setData(response.data);
|
|
174
207
|
}else{
|
|
208
|
+
setScrollData(scrollData||[]);
|
|
175
209
|
setData(data||[]);
|
|
176
210
|
}
|
|
177
211
|
loading.close();
|
|
@@ -186,7 +220,7 @@ const usePagination=(props)=>{
|
|
|
186
220
|
}
|
|
187
221
|
|
|
188
222
|
const reset= ()=>{
|
|
189
|
-
return update({pagination:{current:1},clear:true})
|
|
223
|
+
return update({pagination:{current:1,cursor:''},clear:true})
|
|
190
224
|
}
|
|
191
225
|
|
|
192
226
|
const addListener=(type,fn)=>{
|
|
@@ -223,13 +257,15 @@ const usePagination=(props)=>{
|
|
|
223
257
|
data,
|
|
224
258
|
addListener,
|
|
225
259
|
removeListener,
|
|
226
|
-
loading
|
|
260
|
+
loading,
|
|
261
|
+
mode,
|
|
262
|
+
scrollData
|
|
227
263
|
}
|
|
228
|
-
},[pagination,data,refListener,loading])
|
|
264
|
+
},[pagination,data,refListener,loading,mode,scrollData])
|
|
229
265
|
|
|
230
266
|
return action;
|
|
231
267
|
}
|
|
232
|
-
|
|
268
|
+
usePagination.MODE=MODE;
|
|
233
269
|
|
|
234
270
|
|
|
235
271
|
/**
|
|
@@ -296,6 +332,9 @@ const usePagination=(props)=>{
|
|
|
296
332
|
* @property {function} addListener - 监听事件 (type='beforeService'|'afterService',fn:FunListener)=>object
|
|
297
333
|
* @property {function} removeListener - 移除监听事件 (type,fn:FunListener)=>void
|
|
298
334
|
* @property {object} loading - loading状态,它是一个useSwitch
|
|
335
|
+
* @property {string} [mode='pagination'] - pagination普通分页形式, scrollLoad 滚动加载
|
|
336
|
+
* @property {Object[]} scrollData - 滚动加载模式下的数据集合
|
|
337
|
+
*
|
|
299
338
|
*/
|
|
300
339
|
|
|
301
340
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @module usePaginationWithForm
|
|
4
4
|
*/
|
|
5
|
-
import { useState,
|
|
5
|
+
import { useState, useEffect } from 'react';
|
|
6
6
|
import usePagination from '../usePagination';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -102,6 +102,7 @@ const usePaginationWithForm = (props) => {
|
|
|
102
102
|
};
|
|
103
103
|
};
|
|
104
104
|
|
|
105
|
+
usePaginationWithForm.MODE=usePagination.MODE;
|
|
105
106
|
|
|
106
107
|
/**
|
|
107
108
|
* usePaginationWithForm的返回对象
|