Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 树形数据的联动选择 #75

Merged
merged 3 commits into from
Sep 10, 2020

Conversation

snowlocked
Copy link

Why

fix #74

How

  1. 添加halfSelect的状态
    i. checkbox 添加一个 indeterminate = { store.isHalfSelected(row) }
    ii. store添加一个储存变量 halfSelection
// config.js
renderCell: function(h, { row, column, store, $index }) {
  return <el-checkbox
    nativeOn-click={ (event) => event.stopPropagation() }
    value={ store.isSelected(row) }
    indeterminate = { store.isHalfSelected(row) }
    disabled={ column.selectable ? !column.selectable.call(null, row, $index) : false }
    on-input={ () => { store.commit('rowSelectedChanged', row); } } />;
},

// watcher.js
data(){
  return {
    // 其他原有的数据...
    halfSelection: [],
    // 其他原有的数据...
  }
}

methods: {
  // 其他原有方法...
  // 该行是否半选
  isHalfSelected(row) {
    const { halfSelection = [] } = this.states;
      return halfSelection.indexOf(row) > -1;
    },
  // 其他原有方法...
}
  1. select-all执行时, 清空halfSelection,并对data进行递归处理
  const changeAllSelectionState = (data, states, selection, status) => {
  let selectionChanged = false;
  // 这里递归解决
  data.forEach((row, index) => {
    if (states.selectable) {
      if (states.selectable.call(null, row, index) && toggleRowStatus(selection, row, status)) {
        selectionChanged = true;
      }
    } else {
      if (toggleRowStatus(selection, row, status)) {
        selectionChanged = true;
      }
    }
    if (row[states.childrenColumnName]) {
      selectionChanged = changeAllSelectionState(row[states.childrenColumnName], states, selection, status) || selectionChanged;
    }
  });

  return selectionChanged;
};

_toggleAllSelection() {
  // 原来的逻辑... 
  states.halfSelection = []; // 清空halfSelection
  const selectionChanged = changeAllSelectionState(data, states, selection, value);
  // 原来的逻辑...
}
  1. 勾选某一行时,需要同步子数据和父数据,并且递归执行
 toggleRowSelection(row, selected, emitChange = true) {
  let changed = toggleRowStatus(this.states.selection, row, selected);
  const {
    checkStrictly,
    childrenColumnName,
    data = []
  } = this.states;
  selected = this.isSelected(row);
  // 切换半选状态
  const toggleHalfSelect = (row, isHalfSelected) => {
    if (typeof isHalfSelected !== 'boolean') {
      isHalfSelected = this.isHalfSelected(row) && !selected;
    }
    toggleRowStatus(this.states.halfSelection, row, isHalfSelected);
  };
  toggleHalfSelect(row);
  // 同步子级数据及父级数据
  if (!checkStrictly) {
    // 同步子级数据
    // 递归调用子数据
    const asyncChildrenData = (row) => {
      if (row[childrenColumnName]) {
        row[childrenColumnName].forEach(child => {
          changed = toggleRowStatus(this.states.selection, child, selected) || changed;
          toggleHalfSelect(child);
          asyncChildrenData(child);
        });
      }
    };
    asyncChildrenData(row);
    // 同步父数据
    // 兄弟数据状态查找
    // 兄弟全为选中,父数据添加进selection,再递归同步父数据
    // 兄弟不全为选中,selection移除父数据,父数据添加进halfSelection,递归父数据添加进halfSelection
    const asyncParentData = (parentData, current, childKey) => {
      const parent = findParentData(parentData, current, childKey);
      if (parent) {
        const isAllSelected = parent[childKey].every(this.isSelected);
        const isSomeSelected = parent[childKey].some(child => this.isSelected(child) || this.isHalfSelected(child));
        toggleHalfSelect(parent, isSomeSelected && !isAllSelected);
        changed = toggleRowStatus(this.states.selection, parent, isAllSelected) || changed;
        asyncParentData(parentData, parent, childKey);
      }
    };
    asyncParentData(data, row, childrenColumnName);
  }
  // 其他原有方法...
},
   

效果

1

@auto-add-label auto-add-label bot added the enhancement New feature or request label Sep 9, 2020
@netlify
Copy link

netlify bot commented Sep 9, 2020

Deploy preview for femessage-element ready!

Built with commit 5ef3c07

https://deploy-preview-75--femessage-element.netlify.app

@@ -39,6 +39,7 @@ export const cellForced = {
return <el-checkbox
nativeOn-click={ (event) => event.stopPropagation() }
value={ store.isSelected(row) }
indeterminate={ store.isHalfSelected(row) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isHalfSelected 类似这种命名,看看 el-tree 是怎样的,保持概念的一致性

@levy9527 levy9527 merged commit 9735eff into FEMessage:dev Sep 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

el-table全选不能选中子内容
4 participants