sinooa-redux-crud

1.4.1 • Public • Published

sinooa-redux-crud

tested with jest

适用于中科软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>);
}

规范示例

sinooa-redux-crud-web-demo

状态

一个crud业务(例如名称为jfw)的状态结构如下:

STATE_ROOT
|__ jfw
    |___ records
         |___ '1'
              |___ id: '1'
              |___ title: '开发sinooa-crud-redux@1.0.0'
              |___ done: true
         |___ '2'
              |___ id: '2'
              |___ title: '开发sinooa-workflow-redux@1.0.0'
              |___ done: false
         |___ '3'
              |___ id: '3'
              |___ title: '开发react-native-sinooa-workflow@1.0.0'
              |___ 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 - 当创建数据时,列表需要做出的响应

Readme

Keywords

none

Package Sidebar

Install

npm i sinooa-redux-crud

Weekly Downloads

0

Version

1.4.1

License

MIT

Last publish

Collaborators

  • jackingliu