sinooa-redux-crud
v1.4.1
Published
适合中科软OA产品的CRUD业务的通用Redux实现。
Downloads
8
Readme
sinooa-redux-crud
适用于中科软OA产品的CRUD业务的通用Redux实现。
sinooa-redux-crud实现:
- 业务的各种数据列表分页加载
- 业务数据的删除、新增、修改
- 草稿
- 删除、新增、修改与数据列表的同步
- 包括ActionTypes、Actions、Reducers、Sagas、Selectors
安装
先在项目中添加依赖
yarn add sinooa-redux-crud
或者
npm install --save sinooa-redux-crud
试用
采用redux管理状态,需要有ActionTypes、ActionCreators、reducer、saga和store。接下来,就用sinooa-redux-crud来实现redux状态管理。
首先通过create-react-app创建一个react应用,添加相关依赖,然后在这个demo项目中添加以下代码文件。
jfw.js
:
import { ActionTypes, ActionCreators, createReducers, createSagas } from 'sinooa-redux-crud';
import { create } from 'apisauce';
const http = create({
baseURL: '/api',
});
const moduleId = 'jfw';
const idPropertyName = 'id'; //业务数据中的id属性名
const listTypes = ['todos', 'related']; //列表类别
const baseUrl = '/spring/archives/out/jfw';
const actionTypes = new ActionTypes(moduleId, listTypes);
const actionCreators = new ActionCreators(moduleId, idPropertyName, listTypes);
const reducers = createReducers(moduleId, idPropertyName, listType);
const saga = createSagas(http, moduleId, baseUrl, idPropertyName, listType);
export { actionTypes, actionCreators, reducers, saga };
store.js
:
import { ActionTypes, ActionCreators, createReducers, createSagas } from 'sinooa-redux-crud';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import createSagaMiddleware from 'redux-saga';
import { create } from 'apisauce';
import { reducers, saga } from './jfw';
const sagaMiddleware = createSagaMiddleware();
const enhancer = compose(applyMiddleware(sagaMiddleware));
const store = createStore(combineReducers({
jfw: reducers,
}), enhancer);
sagaMiddle.run(rootSaga);
export default store;
components/JfwList.js
:
import React from 'react';
export default function({
items,
pageNo,
onRequestFetch,
}) {
return (
<div>
<button onClick={() => onRequestFetch(0) }>刷新</button>
<button onClick={() => onRequestFetch(pageNo + 1)}>加载下一页</buton>
<ul>{items.map(item => <li>{item.title}</li>)}</ul>
</div>);
}
containers/JfwList.js
:
import { connect } from 'react-redux';
import JfwList from '../components/JfwList';
import { actionCreators } from '../jfw';
const mapStateToProps = state => ({
items: state.jfw.todos.map(id => state.jfw.records[id]),
pageNo: state.jfw.todosPage.number,
});
const mapDispatchToProps = dispatch => ({
onRequestFetch: pageNo => dispatch(actionCreators.fetchTodos('userId', pageNo, 15))
});
export default connect(mapStateToProps, mapDispatchToProps)(JfwList);
App.js
:
import React from 'react';
import { Provider } from 'react-redux';
import JfwList from './containers/JfwList';
import store from './store';
export default function() {
return (<Provider store={store}>
<JfwList />
</Provider>);
}
规范示例
状态
一个crud业务(例如名称为jfw)的状态结构如下:
STATE_ROOT
|__ jfw
|___ records
|___ '1'
|___ id: '1'
|___ title: '开发[email protected]'
|___ done: true
|___ '2'
|___ id: '2'
|___ title: '开发[email protected]'
|___ done: false
|___ '3'
|___ id: '3'
|___ title: '开发[email protected]'
|___ done: false
|___ todos: ['2', '3']
|___ all: ['1', '2', '3']
|___ related: ['1', '2']
|___ draft: ['3']
|___ createStatus: 'DOING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ createError: '创建失败的错误描述'
|___ deleteStatus: 'DOING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ deleteError: '删除失败的错误描述'
|___ updateStatus: 'DOING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ updateError: '更新失败的错误描述'
|___ fetchTodosStatus: 'FETCHING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ fetchTodosError: '加载待办列表失败的描述'
|___ fetchTodosPageNo: 0
|___ todosPage
|___ number: 0 ---- 当前页数
|___ size: 15 ---- 一页包含项目的数量
|___ totalPages: 1 ---- 总页数
|___ totalElements: 3 ---- 总项目数目
|___ numberOfElements: 3 ---- 当前页包含项目的数量
|___ last: true ---- 最后一页
|___ first: true ---- 第一页
|___ todosFilterConditions: {} ----- 待办列表的过滤条件
|___ todosSort: [ ['createDate', 'desc'], ['updateDate', 'asc']] ------- 待办列表的排序设置
|___ fetchAllStatus: 'FETCHING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ fetchAllError: '加载待办列表失败的描述'
|___ fetchAllPageNo: 0
|___ allPage
|___ number: 0 ---- 当前页数
|___ size: 15 ---- 一页包含项目的数量
|___ totalPages: 1 ---- 总页数
|___ totalElements: 3 ---- 总项目数目
|___ numberOfElements: 3 ---- 当前页包含项目的数量
|___ last: true ---- 最后一页
|___ first: tru ---- 第一页
|___ allFilterConditions: {} ----- 全部列表的过滤条件
|___ allSort: [ ['createDate', 'desc'], ['updateDate', 'asc']] ------- 全部列表的排序设置
|___ fetchRelatedStatus: 'FETCHING' | 'SUCCESS' | 'FAILURE' | 'NORMAL'
|___ fetchRelatedError: '加载待办列表失败的描述'
|___ fetchRelatedPageNo: 0
|___ relatedPage
|___ number: 0 ---- 当前页数
|___ size: 15 ---- 一页包含项目的数量
|___ totalPages: 1 ---- 总页数
|___ totalElements: 3 ---- 总项目数目
|___ numberOfElements: 3 ---- 当前页包含项目的数量
|___ last: true ---- 最后一页
|___ first: true ---- 第一页
|___ relatedFilterConditions: {} ----- 待办列表的过滤条件
|___ relatedSort: [ ['createDate', 'desc'], ['updateDate', 'asc']] ------- 待办列表的排序设置
关于业务的数据是存储在records
中的,这是一个业务主键id与业务数据对应的map。
列表中存储的是业务主键id,如todos: ['2', '3']
,related: ['1', '2']
。
动作
动作类型
以局发文(jfw)为例:
import { ActionTypes } from 'sinooa-crud-workflow';
const actionTypes = new ActionTypes('jfw');
| 获取方式 | 动作类型 | 动作类型描述 |
| ------- | ------- | --------- |
| actionTypes.createStart
| JFW_CREATE_START
| 开始创建局发文 |
| actionTypes.createSuccess
| JFW_CREATE_SUCCESS
| 创建局发文成功 |
| actionTypes.createFailure
| JFW_CREATE_FAILURE
| 创建局发文失败 |
| actionTypes.resetCreateStatus
| JFW_RESET_CREATE_STATUS
| 重置创建状态 |
| actionTypes.updateStart
| JFW_UPDATE_START
| 开始更新局发文 |
| actionTypes.updateSuccess
| JFW_UPDATE_SUCCESS
| 更新局发文成功 |
| actionTypes.updateFailure
| JFW_UPDATE_FAILURE
| 更新局发文失败 |
| actionTypes.resetUpdateStatus
| JFW_RESET_UPDATE_STATUS
| 重置更新状态 |
| actionTypes.deleteStart
| JFW_DELETE_START
| 开始删除局发文 |
| actionTypes.deleteSuccess
| JFW_DELETE_SUCCESS
| 删除局发文成功 |
| actionTypes.deleteFailure
| JFW_DELETE_FAILURE
| 删除局发文失败 |
| actionTypes.resetDeleteStatus
| JFW_RESET_DELETE_STATUS
| 重置删除状态 |
| actionTypes.fetchRecordStart
| JFW_FETCH_RECORD_START
| 开始加载单个数据 |
| actionTypes.fetchRecordSuccess
| JFW_FETCH_RECORD_SUCCESS
| 加载单个数据成功 |
| actionTypes.fetchRecordFailure
| JFW_FETCH_RECORD_FAILURE
| 加载单个数据失败 |
| actionTypes.resetFetchRecordStatus
| JFW_RESET_FETCH_RECORD_STATUS
| 重置加载单个数据的状态 |
| actionTypes.fetchTodosStart
| JFW_FETCH_TODOS_START
| 开始加载待办列表 |
| actionTypes.fetchTodosSuccess
| JFW_FETCH_TODOS_SUCCESS
| 加载待办列表成功 |
| actionTypes.fetchTodosFailure
| JFW_FETCH_TODOS_FAILURE
| 加载待办列表失败 |
| actionTypes.resetFetchTodosStatus
| JFW_RESET_FETCH_TODOS_STATUS
| 重置加载待办列表的状态 |
| actionTypes.fetchAllStart
| JFW_FETCH_ALL_START
| 开始包含所有数据的列表 |
| actionTypes.fetchAllSuccess
| JFW_FETCH_ALL_SUCCESS
| 加载包含所有数据的列表成功 |
| actionTypes.fetchAllFailure
| JFW_FETCH_ALL_FAILURE
| 加载包含所有数据的列表失败 |
| actionTypes.resetFetchAllStatus
| JFW_RESET_FETCH_ALL_STATUS
| 重置加载包含所有数据的列表状态 |
| actionTypes.fetchReleatedStart
| JFW_FETCH_RELATED_START
| 开始加载相关数据列表 |
| actionTypes.fetchRelatedSuccess
| JFW_FETCH_RELATED_SUCCESS
| 加载相关数据列表成功 |
| actionTypes.fetchRelatedFailure
| JFW_FETCH_RELATED_FAILURE
| 加载相关数据列表失败 |
| actionTypes.resetFetchRelatedStatus
| JFW_RESET_FETCH_RELATED_STATUS
| 重置加载相关数据列表状态 |
| actionTypes.fetchDraftStart
| JFW_FETCH_DRAFT_START
| 开始加载草稿数据列表 |
| actionTypes.fetchDraftSuccess
| JFW_FETCH_DRAFT_SUCCESS
| 加载草稿数据列表成功 |
| actionTypes.fetchDraftFailure
| JFW_FETCH_DRAFT_FAILURE
| 加载草稿数据列表失败 |
| actionTypes.resetFetchDraftStatus
| JFW_RESET_FETCH_DRAFT_STATUS
| 重置加载草稿列表状态 |
| actionTypes.resetRecordStatus
| JFW_RESET_RECORD_STATUS
| 重置单条业务数据相关的状态 |
动作创建器
以局发文(jfw)为例:
import { ActionCreators } from 'sinooa-crud-redux';
const actionCreators = new ActionCreators('jfw', 'id');
| 动作创建器 | 动作类型 | 动作类型描述 |
| ------- | ------- | --------- |
| actionCreators.createStart(record)
| JFW_CREATE_START
| 开始创建局发文 |
| actionCreators.createSuccess(record)
| JFW_CREATE_SUCCESS
| 创建局发文成功 |
| actionCreators.createFailure(error)
| JFW_CREATE_FAILURE
| 创建局发文失败 |
| actionCreators.resetCreateStatus()
| JFW_RESET_CREATE_STATUS
| 重置创建状态 |
| actionCreators.updateStart(record)
| JFW_UPDATE_START
| 开始更新局发文 |
| actionCreators.updateSuccess(record)
| JFW_UPDATE_SUCCESS
| 更新局发文成功 |
| actionCreators.updateFailure(record)
| JFW_UPDATE_FAILURE
| 更新局发文失败 |
| actionCreators.resetDeleteStatus()
| JFW_RESET_DELETE_STATUS
| 重置删除状态 |
| actionCreators.deleteStart(id)
| JFW_DELETE_START
| 开始删除局发文 |
| actionCreators.deleteSuccess(id)
| JFW_DELETE_SUCCESS
| 删除局发文成功 |
| actionCreators.deleteFailure(error)
| JFW_DELETE_FAILURE
| 删除局发文失败 |
| actionCreators.resetDeleteStatus()
| JFW_RESET_DELETE_STATUS
| 重置删除状态 |
| actionCreators.fetchRecordStart(id)
| JFW_FETCH_RECORD_START
| 开始加载单个数据 |
| actionCreators.fetchRecordSuccess(record)
| JFW_FETCH_RECORD_SUCCESS
| 加载单个数据成功 |
| actionCreators.fetchRecordFailure(error)
| JFW_FETCH_RECORD_FAILURE
| 加载单个数据失败 |
| actionCreators.resetFetchRecordStatus()
| JFW_RESET_FETCH_RECORD_STATUS
| 重置加载单个数据的状态 |
| actionCreators.fetchTodosStart(userId, pageNo, pageSize, filterCondition?, sort?)
| JFW_FETCH_TODOS_START
| 开始加载待办列表 |
| actionCreators.fetchTodosSuccess(page)
| JFW_FETCH_TODOS_SUCCESS
| 加载待办列表成功 |
| actionCreators.fetchTodosFailure(error)
| JFW_FETCH_TODOS_FAILURE
| 加载待办列表失败 |
| actionCreators.resetFetchTodosStatus()
| JFW_RESET_FETCH_TODOS_STATUS
| 重置加载待办列表的状态 |
| actionCreators.fetchAllStart(userId, pageNo, pageSize, filterCondition?, sort?)
| JFW_FETCH_ALL_START
| 开始包含所有数据的列表 |
| actionCreators.fetchAllSuccess(page)
| JFW_FETCH_ALL_SUCCESS
| 加载包含所有数据的列表成功 |
| actionCreators.fetchAllFailure(error)
| JFW_FETCH_ALL_FAILURE
| 加载包含所有数据的列表失败 |
| actionCreators.resetFetchAllStatus()
| JFW_RESET_FETCH_ALL_STATUS
| 重置加载包含所有数据的列表状态 |
| actionCreators.fetchReleatedStart(userId, pageNo, pageSize, filterCondition?, sort?)
| JFW_FETCH_RELATED_START
| 开始加载相关数据列表 |
| actionCreators.fetchRelatedSuccess(page)
| JFW_FETCH_RELATED_SUCCESS
| 加载相关数据列表成功 |
| actionCreators.fetchRelatedFailure(error)
| JFW_FETCH_RELATED_FAILURE
| 加载相关数据列表失败 |
| actionCreators.resetFetchRelatedStatus()
| JFW_RESET_FETCH_RELATED_STATUS
| 重置加载相关数据列表状态 |
| actionCreators.fetchDraftStart(userId, pageNo, pageSize, filterCondition?, sort?)
| JFW_FETCH_DRAFT_START
| 开始加载草稿数据列表 |
| actionCreators.fetchDraftSuccess(page)
| JFW_FETCH_DRAFT_SUCCESS
| 加载草稿数据列表成功 |
| actionCreators.fetchDraftFailure(error)
| JFW_FETCH_DRAFT_FAILURE
| 加载草稿数据列表失败 |
| actionCreators.resetFetchDraftStatus()
| JFW_RESET_FETCH_DRAFT_STATUS
| 重置加载草稿列表状态 |
| actionTypes.resetRecordStatus(recordId)
| JFW_RESET_RECORD_STATUS
| 重置单条业务数据相关的状态 |
说明:
filterCondition
- 表示过滤条件。形如{ title: '标题' }
sort
- 指定排序规则。形如[['startDate', 'desc'], ['endDate, 'asc']]
API说明
创建reducer
import { createReducer } from 'sinooa-redux-crud';
const moduleId = 'fawen';
const idPropertyName = 'id';
const listTypes = [{
name: 'todos',
onlySaveCurrentPageData: true,
saveDataToRecords: true,
}, 'related', 'all'];
const reducer = createReducer(moduleId, idPropertyName, listTypes);
重点介绍一下listTypes
的配置。listTypes
是用来定义数据列表的。它是一个数组。数据中包含对数据列表的定义,这些定义包括:
name
- 数据列表的名称onlySaveCurrentPageData
- 是否只存储当前加载页的数据。默认为false
,表示存储所有页的数据。saveDataToRecords
- 保存数据到公共的records
中。默认为true
。onDeleteRecord
- 当发生删除操作时,列表需要做的响应onUpdateRecord
- 当发生数据更新操作时,列表需要做的响应onCreateRecord
- 当创建数据时,列表需要做出的响应