《问题总结》frontpagesetting企业分类排序之后,修改下拉选项值,排序列表重新回到原始状态
问题描述
在做企业frontpagesetting的时候,有个分类列表,需要支持对分类进行排序,但是在对分类排序之后,然后修改下拉选项值,排序列表重新回到了原始状态
问题分析
在组件生命周期getDerivedStateFromProps方法中,比对props, state中的list数据,因为displayType是可变的,所以会判断 R.symmetricDifference不为空,从而导致重新赋值state的list值,造成排序被还原
解决方法
思路:
知道上面是因为排序之后在修改下拉选项值之后,导致的列表顺序还原,displayType是可变的。基于这个原因,不使用list来判断,而是使用itemIds单个的id数组,这样不管顺序怎么排列,和displayType的值怎么修改都不会造成顺序还原。
代码实现:
1、生命周期函数getDerivedStateFromProps中比对id数组,并赋值给state的itemIds
static getDerivedStateFromProps(props, state) {
if (
!R.isEmpty(
R.symmetricDifference(
R.pluck(props.draggableId, props.dataSource),
state.itemIds
)
)
) {
return {
itemIds: R.pluck(props.draggableId, props.dataSource)
}
}
return null
}
2、渲染数据列表时候 ,通过遍历itemIds,根据id从dataSource中获取并显示相关filed字段
{this.state.itemIds.map((id, index) => {
const item = R.find(R.propEq(draggableId, id), dataSource)
return (
{(provided2, snapshot2) => (
{this.renderDraggableContent(item)}
)}
)
})}
3、监听排序函数,将排序后的itemIds传递到父组件中
onDragEnd = result => {
const { destination, source } = result
const { onOrderChange } = this.props
// dropped outside the list
if (R.isNil(destination)) return
// dropped in same position
if (
R.allPass([R.eqProps('droppableId'), R.eqProps('index')])(
destination,
source
)
) {
return
}
this.setState(
prevState => ({
itemIds: this.reorder(
prevState.itemIds,
source.index,
destination.index
)
}),
() => {
onOrderChange(this.state.itemIds)
}
)
}
reorder = (list, startIndex, endIndex) => {
const newOrder = R.insert(
endIndex,
list[startIndex],
R.remove(startIndex, 1, list)
)
return newOrder
}
4、父组件监听到排序函数重新表单赋值
handleOrderChange = newOrder => {
this.props.form.setFieldsValue({
order: newOrder
})
}
{getFieldDecorator('order', {
initialValue: corporateFrontpageCategoryList
.map(corpCat => corpCat.get('corporateCategoryNo'))
.toArray()
})( )}
5、selector中处理接口返回的controlSetting数据,在corporateCategoryList中添加列表所需要的name字段
export const getCorporateFrontpageCategoryList = createSelector(
getCorporateCategoryList,
controlSettingSelector,
(corporateCategoryList, controlSetting) => {
if (R.isNil(corporateCategoryList) || R.isNil(controlSetting)) {
return List()
}
return controlSetting
.get('corporateCategoryList')
.map(frontpageCorpCat =>
frontpageCorpCat.set(
'name',
corporateCategoryList
.find(
(corpCat, key, iter) =>
corpCat.get('corporateCategoryNo') ===
frontpageCorpCat.get('corporateCategoryNo')
)
.get('name')
)
)
}
)
6、在getCorporateCategoryColumns中使用displayType.${corporateCategoryNo}.displayType形式给select赋值
数据格式 displayType: {CORPCATE10034: {…}, CORPCATE10091: {…}, CORPCATE10093
{
title: i18n.t('corporateFrontpageSetting.label.imgStyle'),
dataIndex: 'corporateCategory.displayType',
key: 'displayType',
render: ({ corporateCategoryNo, displayType }: Object, index: number) => {
return getFieldDecorator(
`displayType.${corporateCategoryNo}.displayType`,
{
initialValue: displayType
}
)(
)
}
},
//删除列表行数据
{
title: i18n.t('corporateFrontpageSetting.label.action'),
dataIndex: 'corporateCategory.action',
width: 100,
key: 'action',
render: (record: Object) => {
const updatedFrontpageCorporateCategoryList = corporateCategoryList.filterNot(
item => item.get('corporateCategoryNo') === record.corporateCategoryNo
)
return (
)
}
}
7、最后请求保存接口的时候对数据做处理
解构formValues中除了order和displayType的数据,处理并组装corporateCategoryList数据,最后拼装并返回接口请求所需格式
corporateHome: {articleIds: Array(4), displayCorporateCategory: "CORPCATE10077"}
corporateCategoryList: (6) [{…}, {…}, {…}, {…}, {…}, {…}]
patchFormValues = formValues => {
return {
...R.omit(['order', 'displayType'])(formValues),
corporateCategoryList: R.map(
corporateCategoryNo => ({
corporateCategoryNo,
displayType: R.path(
['displayType', corporateCategoryNo, 'displayType'],
formValues
)
}),
R.path(['order'])(formValues)
)
}
}