1.4.1 • Published 6 years ago

sinooa-redux-crud v1.4.1

Weekly downloads
1
License
MIT
Repository
-
Last release
6 years ago

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.createStartJFW_CREATE_START开始创建局发文
actionTypes.createSuccessJFW_CREATE_SUCCESS创建局发文成功
actionTypes.createFailureJFW_CREATE_FAILURE创建局发文失败
actionTypes.resetCreateStatusJFW_RESET_CREATE_STATUS重置创建状态
actionTypes.updateStartJFW_UPDATE_START开始更新局发文
actionTypes.updateSuccessJFW_UPDATE_SUCCESS更新局发文成功
actionTypes.updateFailureJFW_UPDATE_FAILURE更新局发文失败
actionTypes.resetUpdateStatusJFW_RESET_UPDATE_STATUS重置更新状态
actionTypes.deleteStartJFW_DELETE_START开始删除局发文
actionTypes.deleteSuccessJFW_DELETE_SUCCESS删除局发文成功
actionTypes.deleteFailureJFW_DELETE_FAILURE删除局发文失败
actionTypes.resetDeleteStatusJFW_RESET_DELETE_STATUS重置删除状态
actionTypes.fetchRecordStartJFW_FETCH_RECORD_START开始加载单个数据
actionTypes.fetchRecordSuccessJFW_FETCH_RECORD_SUCCESS加载单个数据成功
actionTypes.fetchRecordFailureJFW_FETCH_RECORD_FAILURE加载单个数据失败
actionTypes.resetFetchRecordStatusJFW_RESET_FETCH_RECORD_STATUS重置加载单个数据的状态
actionTypes.fetchTodosStartJFW_FETCH_TODOS_START开始加载待办列表
actionTypes.fetchTodosSuccessJFW_FETCH_TODOS_SUCCESS加载待办列表成功
actionTypes.fetchTodosFailureJFW_FETCH_TODOS_FAILURE加载待办列表失败
actionTypes.resetFetchTodosStatusJFW_RESET_FETCH_TODOS_STATUS重置加载待办列表的状态
actionTypes.fetchAllStartJFW_FETCH_ALL_START开始包含所有数据的列表
actionTypes.fetchAllSuccessJFW_FETCH_ALL_SUCCESS加载包含所有数据的列表成功
actionTypes.fetchAllFailureJFW_FETCH_ALL_FAILURE加载包含所有数据的列表失败
actionTypes.resetFetchAllStatusJFW_RESET_FETCH_ALL_STATUS重置加载包含所有数据的列表状态
actionTypes.fetchReleatedStartJFW_FETCH_RELATED_START开始加载相关数据列表
actionTypes.fetchRelatedSuccessJFW_FETCH_RELATED_SUCCESS加载相关数据列表成功
actionTypes.fetchRelatedFailureJFW_FETCH_RELATED_FAILURE加载相关数据列表失败
actionTypes.resetFetchRelatedStatusJFW_RESET_FETCH_RELATED_STATUS重置加载相关数据列表状态
actionTypes.fetchDraftStartJFW_FETCH_DRAFT_START开始加载草稿数据列表
actionTypes.fetchDraftSuccessJFW_FETCH_DRAFT_SUCCESS加载草稿数据列表成功
actionTypes.fetchDraftFailureJFW_FETCH_DRAFT_FAILURE加载草稿数据列表失败
actionTypes.resetFetchDraftStatusJFW_RESET_FETCH_DRAFT_STATUS重置加载草稿列表状态
actionTypes.resetRecordStatusJFW_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 - 当创建数据时,列表需要做出的响应
1.4.1

6 years ago

1.4.0

6 years ago

1.3.2

7 years ago

1.3.1

7 years ago

1.3.0

7 years ago

1.2.2

7 years ago

1.2.1

7 years ago

1.2.0

7 years ago

1.1.0

7 years ago

1.0.1

7 years ago

1.0.0

7 years ago