表格-分页组件
单页面分页参数处理方式
单页面分页,适用于存在分页显示的页面,包括如何处理Form参数数据。考虑的页面性能,通常把一个页面根据功能的不同划分不同的子组件
├─hmdm
│  └─Uom
│   └─index.js
|   └─FilterForm.js
|   └─ListTable.js
|   └─index.less
在业务组件的入口文件(index.js)中,引入定义好的子组件
// index.js
render(){
    const filterProps = {};
    const listProps  ={};
    return (
        <React.Fragement>
            <Header/>
            <Content>
                <div>
                    <FilterForm {...filterProps} />
                </div>
                <ListTable {...listProps} />
            </Content>
        </React.Fragement>
    )
}
将入口文件中的Form创建转移到子组件的FilterForm中,以此缩小页面render时的作用范围,提升页面性能
// bad
// index.js
@Form.create({fieldNameProp: null})
export default class MessageTemplate extends PureComponent {}
// good
// FilterForm.js
@Form.create({ fieldNameProp: null })
export default class FilterForm extends PureComponent {}
在index.js中进行查询操作时,可以获取Form实时的参数值,需要将FilterForm中的Props Form传递到index.js中
// index.js
export default class MessageTemplate extends PureComponent {
    // 将查询表单的值绑定到this上
    form;
    // 将FilterForm中的form属性存储到index.js的state中
    @Bind()
    handleBindRef(ref = {}) {
        this.form = (ref.props||{}).form;
    }
    render(){
        const filterProps = {
            onSearch: this.handleSearch,
            onRef: this.handleBindRef
        }
        return();
    }
}
// FilterForm.js
@Form.create({ fieldNameProp: null })
export default class FilterForm extends PureComponent {
    constructor(props) {
      super(props);
      props.onRef(this);
    }
}
页面查询的参数处理
export default class MessageTemplate extends PureComponent {
    @Bind()
    handleSearch(fields = {}) {
      const { dispatch } = this.props;
      // 实时获取查询表单中查询参数
      const filterValues = isUndefined(this.form) ? {} : filterNullValueObject(this.form.getFieldsValue());
      dispatch({
        type: 'uom/fetchUomData',
        payload: {
          page: isEmpty(fields) ? {} : fields,
          ...filterValues,
        },
      });
    }
    render(){
        const filterProps = {
            onSearch: this.handleSearch,
            onRef: this.handleBindRef,
        };
        const listProps = {
            onSearch: this.handleSearch,
            // otherProps;
        }
        return ();
    }
}
export default class ListTable extends PureComponent {
    
    render(){
        const { onSearch, ...otherProps } = this.props;
        return (
            <Table
                {...otherProps}
                onChange={page => onSearch(page)}
            />
        )
    }
}
@Form.create({ fieldNameProp: null })
export default class FilterForm extends PureComponent {
    @Bind()
    searchOption(){
        const { onSearch, form } = this.props;
        form.validator(err => {
            if(!err) {
                onSearch(); // 不传任何参数,表单值在index中实时获取
            }
        })
    }
}
// 业务组件对应的model
export default {
    namespace: 'uom',
    state: {
        list: [], // 列表数据
        pagination: {}, // 查询参数
    },
    effects: {
        *fecthUomData({ payload }, { call, put }) {
            const result = getResponse(yield call(searchData, payload));
            if(result) {
                yield put({
                    type: 'updateState',
                    payload: {
                        list: result.content,
                        pagination: createPagination(result), // pagination会保存到model中
                    }
                });
            }
        }
    },
    reducers: {
        updateState(state, {payload}) {
            return {
                ...state,
                ...payload,
            };
        }
    }
}
// 对应的service中的进行参数过滤处理
// uomService.js
export async function searchData(params){
  // 调用parseParamters进行参数过滤
  const param = parseParameters(params);
  return request(`${prefix}/uom`, {
    method: 'GET',
    query: param,
  });
}
页面操作(保存、更新)后,页面数据需要刷新,再次调用handleSearch()时,需要传入model中保存的pagination
handleSaveData(){
    const { dispatch, uom: { pagination = {}} } = this.props;
    dispatch({
        type: '',
        payload:{}
    }).then(res => {
        if(res) {
            notificaiton.success();
            // 页面操作成功后,刷新数据时,传入pagination
            this.handleSearch(pagination);
        }
    });
}
跨页面分页参数处理方式
跨页面分页参数,目前只有从明细页退回到列表页一种情形,处理方式主要在列表页的中做一些特殊处理
├─hmsg
│  └─MessageTemplate
|   └─List
│     └─index.js
|     └─FilterForm.js
|     └─ListTable.js
|     └─index.less
|   └─Detail
|     └─index.js
在列表页的FilterForm组件上添加缓存组件CacheComponent,同时,在列表页的入口文件中,componentDidMount()上加入校验
// List/FilterForm.js
@Form.create({ fieldNameProp: null })
@CacheComponent({ cacheKey: '/hmsg/message-template' })
export default class FilterForm extends PureComponent {}
// List/index.js
export default class List extends Component {
  componentDidMount() {
    const {
      dispatch,
      messageTemplate: { pagination },
      location: { state: { _back } = {} },
    } = this.props;
    // 校验是否从详情页返回
    const page = _back === -1 ? pagination : {};
    this.handleSearch(page);
  }
  @Bind()
  handleSearch(fields = {}) {
  }
列表页数据批量操作
页面功能要是实现批量新增,批量修改时,采用行内编辑,行内编辑的使用方式可参考相关文档。对于行新增、行移除时,需要对model中的保存的pagination进行变更,进行简单的方法调用即可
// 新增行, 调用 addItemToPagination
import { addItemToPagination } from 'utils/utils';
@Bind()
handleAddUom() {
  const { dispatch, uom: {list = [], pagination = {} } } = this.props;
  dispatch({
    type: 'uom/updateState',
    payload: {
      // otherProps
      pagination: addItemToPagination(list.length, pagination),
    },
  });
}
// 移除行, 调用 delItemToPagination
import { addItemToPagination } from 'utils/utils';
 
@Bind()
handleCleanLine(record) {
  const { dispatch, uom: { list = [], pagination = {} } } = this.props;
  dispatch({
    type: 'uom/updateState',
    payload: {
      // otherProps
      pagination: delItemToPagination(list.length, pagination),
    },
  });
}