npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sinooa-redux-crud

v1.4.1

Published

适合中科软OA产品的CRUD业务的通用Redux实现。

Downloads

8

Readme

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: '开发[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 - 当创建数据时,列表需要做出的响应