React Ant Design 트 리 표 의 복잡 한 삭제 작업

최근 업무 접촉 으로 antd 를 사용 하여 복잡 한 트 리 표 의 표시 와 수정 을 완 료 했 습 니 다.그 중에서 많은 구 덩이 를 만 났 고 많은 기능 antd 는 초보적인 기능 만 썼 으 며 더욱 세분 화 된 기능 은 스스로 보완 할 수 밖 에 없 었 다.밟 은 구 덩이 는 모두 여기에 쓰 여 있다.
트 리 표 표시
antd 에 서 는 표 의 key 값 에 대해 엄격 한 통 제 를 가지 고 있 습 니 다.모든 row 는 유일한 key 값 이 있어 야 합 니 다.숫자 일 수도 있 고 문자열 일 수도 있 습 니 다.이 점 은 내 가 사 용 했 던 아이 비 와 큰 차이 가 있다.react 는 key 를 사용 하여 모든 줄 을 대표 하 는 것 은 다시 과장 하 는 문 제 를 피하 기 위해 서 이 최적화 도 실제 개발 에서 많은 문 제 를 가 져 왔 다.예 를 들 어 새 줄 을 만 들 때 새 키 를 사용자 정의 해 야 합 니 다.
다음은 코드 와 코드 효 과 를 직접 올 리 겠 습 니 다.이것 은 3 급 트 리 표 이 고 2 급 제목 을 포함 합 니 다.
최종 효과

colums 제목:간이 판 제목,기능 이 증가 함 에 따라 우 리 는 colums 의 복잡 도 를 증가 시 킬 것 입 니 다.

let columns = [
 {
  title: '  ',
  dataIndex: 'text'
 },
 {
  title: '  ',
  children: [
   {
    title: '  ',
    dataIndex: 'text1'
   },
   {
    title: '  ',
    dataIndex: 'text2',
   }]
 },
 {
  title: '  ',
  dataIndex: 'content'
 },
 {
  title: '  ',
  dataIndex: 'answer',
 },
 {
  title: '  ',
  dataIndex: 'mark_type',
  className: 'line'
 },
 {
  title: '  ',
  dataIndex: 'version',
  className: 'line'
 },
 {
  title: '     ',
  dataIndex: 'value1',
  className: 'line'
 },
 {
  title: '     ',
  dataIndex: 'value2',
  className: 'line'
 },
 {
  title: '  ',
  key: 'action',
  width: 205
 }
];

데이터 데이터:

let data = [{
   "key": 1,
   "text": "   ",
   "children": [{
    "key": 11,
    "text1": "   ",
    "children":[]
   }, {
    "key": 12,
    "text1": "   ",
    "value1": "  ",
    "children": [{
     "key": 121,
     "value2": "  ",
     "text2": "   ",
     "content": "    ",
     "answer": "A",
     "mark_type": "1",
     "version": "1"
    },{
     "key": 122,
     "value2":"  ",
     "text2": "   ",
     "content": "    ",
     "answer": "  ",
     "mark_type": "1",
     "version": "1"
    },{
     "key": 123,
     "value2": "  ",
     "text2": "   ",
     "content": "    ",
     "answer": "    ",
     "mark_type": "1",
     "version": "1"
    },{
     "key": 124,
     "value2": "   ",
     "text2": "   ",
     "content": "    ",
     "answer": "    ",
     "mark_type": "1",
     "version": "1"
    }],
   }],
  }, {
   "key": 2,
   "text": "   ",
   "children": [ {
    "key": 21,
    "text1": "   ",
    "value1": "  ",
    "children": [{
     "key": 211,
     "value2": "  ",
     "text2": "    ",
     "content": "    ",
     "answer": "ABC",
     "mark_type": "2",
     "version": "1"
    },{
     "key": 212,
     "value2": "    ",
     "text2": "  ",
     "content": "    ",
     "answer": "D",
     "mark_type": "2",
     "version": "1"
    }],
   }],
  }];
하위 항목 데이터 추가
하위 항목 데 이 터 를 추가 하려 면 작업 중의 추가 단 추 를 사용 하여 증가 하고 추가 단 추 를 도형 으로 설정 하여 더욱 구체 적 이 고 선명 하 게 한다.

 //button    antd  icon  
<Button type="primary" shape="circle" icon="plus" size={'small'}
   onClick={this.handleAdd.bind(this, record)}
 />
주의사항:
1.맨 하위 항목 에 하위 항목 선택 을 추가 하지 않 았 으 므 로 서로 다른 데이터 줄 에 대해 서로 다른 처 리 를 해 야 합 니 다.
2.데이터 줄 에 따라 새로 추 가 된 데이터 의 내용 이 다 르 고 필드 도 다르다.
3.새로 추 가 된 후에 확인 또는 취 소 를 클릭 해 야 합 니 다.
4.데 이 터 를 추가 하고 확인 을 클릭 한 후 현재 key 아래 children 에 추가 해 야 합 니 다.
antd 가 자체 적 으로 가지 고 있 는 editable 속성 을 사용 하려 고 했 지만 이 속성 은 2 급 제목 의 편집 을 지원 하지 않 기 때문에 자신 만 render 를 씁 니 다.
이 문 제 는 7102 년 에 제 기 됐 지만 8102 년 이 다 되 어 9102 년 에 도 업데이트 되 지 않 았 다.
1 단계 형식 제목 스타일 추가

2 단계 형식 제목 스타일 추가

여기 일부 render 코드 만 있 습 니 다:

//    
{
 title: '  ', 
 children: 
 [{
  title: '  ',
  dataIndex: 'text1',
  render: (text, record) => {
   if (this.state.isEditing && this.state.editingOneKey === record.key)
    return <Input defaultValue={text} onChange={(e) => { this.changeEdit(e, record.key, 'text1') }} />
   return text
  }
 },
 {
  title: '  ',
  dataIndex: 'text2',
  render: (text, record) => {
   if (this.state.isEditing && this.state.editingTwoKey === record.key)
    return <Input defaultValue={text} onChange={(e) => { this.changeEdit(e, record.key, 'text2') }} />
   return text
  }
 }]
}

//select  
{
 title: '  ',
 dataIndex:'content',
 render:(text, record) => {
  if (text === 0)
   text = '   ';
  if (text === 1)
   text = '   ';
  if (this.state.isEditing && this.state.editingTwoKey === record.key) {
   return <Select defaultValue={text} onChange={(e) => {
    this.changeEdit(e, record.key, 'flag')
   }} getPopupContainer={triggerNode => triggerNode.parentNode}>
    <Option value='0'>  </Option>
    <Option value='1'>  </Option>
   </Select>
  }
  return text
 }
}

전개 에 주의 하 다
열 리 지 않 은 줄 에 데 이 터 를 추가 하면 열 린 편집 상 태 를 볼 수 없 는 것 은 매우 나 쁜 문제 입 니 다.그래서 우 리 는 하위 항목 을 추가 할 때 자동 으로 부모 항목 을 펼 쳐 야 합 니 다.

//steate    
expandedRows: [] //   
//render    
<Table
  bordered
  expandedRowKeys={this.state.expandedRows}
  onExpandedRowsChange={this.changeExpandedRows.bind(this)}
/>

//      ,       
changeExpandedRows = (expandedRows) => {
  this.setState({
   expandedRows
  })
 };

//     
let rows = this.state.expandedRows;
rows.push(record.key);
this.setState({
 expandedRows: rows
});

줄 데이터 삭제
antd 에서 삭제 하 는 것 은 비교적 간단 합 니 다.antd 의 table 은 줄 마다 key 속성 이 있 기 때문에 key 는 유일 하고 필수 적 인 속성 이기 때문에 목적 key 를 포함 하 는 데 이 터 를 걸 러 내 면 삭제 로 볼 수 있 습 니 다.이것 은 트 리 데이터 이기 때문에 일반적인 옮 겨 다 니 는 것 은 조작 할 수 없 기 때문에 깊이 를 사용 하여 데이터 처 리 를 우선 하고 넓이 를 우선 하여 데이터 에 따라 변경 할 수 있 습 니 다.

handleDelete = (key) => {
  let data = this.state.data;
  data = dsFilter(data, key);

  this.setState({
   data
  });

  function dsFilter(dealData, dealKey) {
   for (let i = 0; i < dealData.length; i++) {
    if (dealData[i].children && dealData[i].children.length > 0) {
     dealData[i].children = dsFilter(dealData[i].children, dealKey);
    }
   }
   return dealData.filter(item => item.key !== dealKey);
  }
 };

일부 필드 수정
새로 추 가 된 colums 와 같 지만 수정 은 이전 값 을 저장 해 야 합 니 다.input 또는 select 에 defaultValue={text}을 설정 하여 초기 값 이 같 도록 해 야 합 니 다.
보존 하 다.
추가 수정 이 든 삭제 든 저장 이 필요 하 다.여기✓와✗를 사용 하여 확정 과 취 소 를 대표 합 니 다.
한 줄 의 편집 에서 다른 줄 의 동작 을 클릭 하면 앞으로 의 동작 을 취소 하 는 것 으로 간주 해 야 합 니 다.

<div>
 <Button shape="circle" icon="check" size={'small'} style={{ backgroundColor: '#65BF34', color: '#FFF', border: 'none' }}
   onClick={this.saveEdit.bind(this, record.key)}
 />
 <Button shape="circle" icon="close" size={'small'} style={{ backgroundColor: '#FF3333', color: '#FFF', border: 'none' }}
   onClick={this.cancelEdit.bind(this, record.key)}
 />
</div>
순 서 를 고치다
수정 순 서 는 데이터 가 배열 에 있 는 순 서 를 수정 하고 간단 한 temp 으로 교환 하면 된다.

shiftUp = (key) => {
  let data = this.state.data;
  data = dsShift(data, key);
  this.setState({
   data
  });

  function dsShift(dealData, dealKey) {
   for (let i = 0; i < dealData.length; i++) {
    if (dealData[i].children && dealData[i].children.length > 0) {
     dealData[i].children = dsShift(dealData[i].children, dealKey);
    }
    if (dealData[i].key === dealKey) {
     if (i === 0) {
      message.warning('     !');
      break;
     }
     let temp = dealData[i - 1];
     dealData[i - 1] = dealData[i];
     dealData[i] = temp;
     break;
    }
   }
   return dealData;
  }
 };

 shiftDown = (key) => {
  let data = this.state.data;
  data = dsShift(data, key);
  this.setState({
   data
  });

  function dsShift(dealData, dealKey) {
   for (let i = 0; i < dealData.length; i++) {
    if (dealData[i].children && dealData[i].children.length > 0) {
     dealData[i].children = dsShift(dealData[i].children, dealKey);
    }
    if (dealData[i].key === dealKey) {
     if (i === dealData.length - 1) {
      message.warning('     !');
      break;
     }
     let temp = dealData[i + 1];
     dealData[i + 1] = dealData[i];
     dealData[i] = temp;
     break;
    }
   }
   return dealData;
  }
 };

총결산
표 데이터 작업 을 할 때 변 수 를 저장 해 야 합 니 다.여기에 더 이상 쓰 지 않 았 습 니 다.전체적으로 말 하면 antd 는 좋 은 구성 요소 로 대부분의 기능 이 완비 되 어 있 지만 많은 세부 사항 은 스스로 보완 해 야 한다.
추가 지식:Antd(Ant-design),하위 표(expanded Row Render)의 비동기 획득 데이터
아 리 의 ant-design 오픈 소스 프레임 워 크 를 사용 합 니 다.표 에 하위 표를 삽입 하려 면 사용자 가 부모 표 의 한 줄 데 이 터 를 클릭 한 후에 이 줄 의 key 를 가 져 온 다음 에 하위 표 의 내용 을 채 워 달라 고 요청 해 야 합 니 다.
이렇게 쓰 면(코드 와 상 관 없 이 생략):

expandedRowRender = (record) => {
 
  dispatch({
    type: 'flow/getPlanList',
    payload: {
      contractId: record.contract_id, //             key
    },
    callback: () => {
      const {
       flow: { data },
      } = this.props; 
 
      this.setState({
       secData: data.list,
      });
 
      console.log("    (PlanList):" + JSON.stringify(this.state.secData));
    }
  });
  
  return (
    <Table
      columns={secColumns}
      dataSource={this.state.secData}
      pagination={false}
    />
  );
};
 
render() {
  return(
    <Card>
     {this.renderForm()}
     <div>
       <Table
        expandedRowRender={this.expandedRowRender}
        loading={loading}
        rowSelection={rowSelection}
        dataSource={list}
        columns={columns}
        pagination={paginationProps}
        scroll={{ x: 2500}}
        size = 'middle' 
        expandRowByClick={true}
        onSelect={this.seFn}
       />
     </div>
    </Card>
  ) 
}
끊임없이 요청 하 는 현상 이 나타 납 니 다:

이 는 expanded Row Render 가 실제 Table 구성 요소 의 render 방법 에서 호출 되 었 기 때 문 입 니 다.React render 에서 dispatch 를 사용 하면 중복 호출 문제 가 발생 할 수 있 습 니 다.dispatch->setState->render->dispatch->setState->render 는 반복 적 으로 호출 됩 니 다.그래서 dispatch 를 onExpand 에 넣 어야 합 니 다.

onExpand = (expanded, record) => {
  const { dispatch } = this.props;
 
  dispatch({
    type: 'flow/getPlanList',
    payload: {
     contractId: record.contract_id,
    },
    callback: () => {
      const {
        flow: { data },
      } = this.props; 
 
      this.setState({
        secData: data.list ,
      });
 
     console.log("    (PlanList):" + JSON.stringify(this.state.secData));
    }
  });
}
그러나 단순히 이렇게 하면 새로운 문 제 를 가 져 올 수 있다.바로 하위 표 의 모든 데이터 가 똑 같이 변 한 다 는 것 이다.
본인 의 해결 방법 은 키 값 을 사용 하 는 것 입 니 다.

onExpand = (expanded, record) => {
  const { dispatch } = this.props;
 
  if (expanded === false) {
   //             ,         ,    ,
   //                      
   console.log("  !");
   this.setState({
    subTabData: {
     ...this.state.subTabData,
     [record.contract_id]: [] ,
    }
   });
  } else {
   console.log("  !");
   dispatch({
    type: 'flow/getPlanList',
    payload: {
     contractId: record.contract_id,
    },
    callback: () => {
     const {
      flow: { data },
     } = this.props; 
 
     this.setState({
      subTabData: {
       ...this.state.subTabData,
       [record.contract_id]: data.list ,
      }
     });
 
     console.log("    (PlanList):" + JSON.stringify(this.state.subTabData));
    }
   });
  }
 }
이상 의 React Ant Design 트 리 표 의 복잡 한 첨삭 과 수정 작업 은 바로 소 편 이 여러분 에 게 공유 한 모든 내용 입 니 다.여러분 께 참고 가 되 고 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기