Browse Source

feat: 新增动态加载的级联组件

lanjianrong 5 years atrás
parent
commit
c9bfafa80f

+ 44 - 0
src/components/LazyCascader/index.jsx

@@ -0,0 +1,44 @@
+import { Cascader } from 'antd'
+import React, { useState, useEffect } from 'react'
+import { connect } from 'dva'
+
+const LazyCascader = props => {
+  const { options, dispatch } = props
+  useEffect(() => {
+    if (!options.length) {
+      dispatch({
+        type: 'district/fetch'
+      })
+    }
+  }, [])
+
+  const onChange = (value, selectedOptions) => {
+    // console.log(value, selectedOptions)
+  }
+
+  const loadData = selectedOptions => {
+    const targetOption = selectedOptions[selectedOptions.length - 1]
+    targetOption.loading = true
+
+    // load options lazily
+    dispatch({
+      type: 'district/fetch',
+      payload: { parentId: targetOption.id, level: targetOption.level }
+    })
+  }
+
+  return (
+    <Cascader
+      options={options}
+      onChange={onChange}
+      loadData={loadData}
+      fieldNames={{ label: 'name', value: 'id' }}
+      changeOnSelect
+    />
+  )
+}
+
+export default connect(({ district, loading }) => ({
+  options: district.data,
+  loadingDistrict: loading.effects['district/fetch']
+}))(LazyCascader)

+ 38 - 6
src/models/district.js

@@ -11,21 +11,53 @@ export default {
       const response = yield call(queryDistrict, payload)
       if (response && response.code === consts.RET_CODE.SUCCESS) {
         yield put({
-          type: 'show',
-          payload: response.data
+          type: 'changeState',
+          payload: {
+            data: response.data,
+            parentId: payload && payload.parentId ? payload.parentId : '',
+            level: payload && payload.level ? payload.level : ''
+          }
         })
-
       }
-      // console.log(response)
     }
   },
   // reducers:用于处理同步操作,由action触发,可修改state
   reducers: {
     // action:是由reducers及effects的触发器,一般是第一个对象,如:{type:'add',payload:todo}
-    show(state, action) {
+    changeState(state, action) {
+      const pid = action.payload && action.payload.parentId
+      const level = action.payload && action.payload.level
+      if (pid) {
+        const newData = state.data && state.data.map(item => {
+          const newItem = item
+          if (level === item.level) {
+            // 第一层
+            if (item.id === pid) {
+              newItem.loading = false
+              newItem.children = action.payload.data
+            }
+          } else {
+            // 第二层
+            newItem.children = item.children && item.children.map(secondItem => {
+
+              const newSecondItem = secondItem
+              if (secondItem.id === pid) {
+                newItem.loading = false
+                newSecondItem.children = action.payload.data
+              }
+              return newSecondItem
+            })
+          }
+          return newItem
+        })
+        return {
+          ...state,
+          data: newData
+        }
+      }
       return {
         ...state,
-        data: action.payload
+        data: action.payload.data
       }
     }
   }

+ 3 - 2
src/pages/Customer/Company/index.jsx

@@ -1,11 +1,12 @@
 import React from 'react'
-import { Card } from 'antd'
+import { Card, Cascader } from 'antd'
+import LazyCascader from '@/components/LazyCascader'
 
 const Company = () => {
-  // const { modalVisible, onCancel } = props;
   return (
     <Card bordered={false}>
       dasdasddad
+      <LazyCascader />
     </Card>
   )
 }