diff --git a/packages/table/src/table-store.js b/packages/table/src/table-store.js index f0a0da0f..3bfbdd97 100644 --- a/packages/table/src/table-store.js +++ b/packages/table/src/table-store.js @@ -19,12 +19,12 @@ const sortData = (data, states) => { return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod); }; -const getSelectedMap = function(states, rowKey) { - const selectionMap = {}; - states.selection.forEach((row, index) => { - selectionMap[getRowIdentity(row, rowKey)] = { row, index }; +const getKeysMap = function(array, rowKey) { + const arrayMap = {}; + (array || []).forEach((row, index) => { + arrayMap[getRowIdentity(row, rowKey)] = { row, index }; }); - return selectionMap; + return arrayMap; }; const toggleRowSelection = function(states, row, selected) { @@ -88,19 +88,24 @@ const TableStore = function(table, initialState = {}) { TableStore.prototype.mutations = { setData(states, data) { + const dataInstanceChanged = states._data !== data; states._data = data; states.data = sortData((data || []), states); this.updateCurrentRow(); - const selection = states.selection; - if (!states.reserveSelection) { - this.clearSelection(); + if (dataInstanceChanged) { + this.clearSelection(); + } else { + this.cleanSelection(); + } + this.updateAllSelected(); } else { const rowKey = states.rowKey; if (rowKey) { - const selectedMap = getSelectedMap(states, rowKey); + const selection = states.selection; + const selectedMap = getKeysMap(selection, rowKey); states.data.forEach((row) => { const rowId = getRowIdentity(row, rowKey); @@ -266,6 +271,35 @@ TableStore.prototype.toggleRowSelection = function(row, selected) { toggleRowSelection(this.states, row, selected); }; +TableStore.prototype.cleanSelection = function() { + const selection = this.states.selection || []; + const data = this.states.data; + const rowKey = this.states.rowKey; + let deleted; + if (rowKey) { + deleted = []; + const selectedMap = getKeysMap(selection, rowKey); + const dataMap = getKeysMap(data, rowKey); + for (let key in selectedMap) { + if (selectedMap.hasOwnProperty(key) && !dataMap[key]) { + deleted.push(selectedMap[key].row); + } + } + } else { + deleted = selection.filter((item) => { + return data.indexOf(item) === -1; + }); + } + + deleted.forEach((deletedItem) => { + selection.splice(selection.indexOf(deletedItem), 1); + }); + + if (deleted.length) { + this.table.$emit('selection-change', selection); + } +}; + TableStore.prototype.updateAllSelected = function() { const states = this.states; const { selection, rowKey, selectable, data } = states; @@ -276,7 +310,7 @@ TableStore.prototype.updateAllSelected = function() { let selectedMap; if (rowKey) { - selectedMap = getSelectedMap(states, rowKey); + selectedMap = getKeysMap(states.selection, rowKey); } const isSelected = function(row) { diff --git a/test/unit/specs/table.spec.js b/test/unit/specs/table.spec.js index 7f504c80..b4c6d000 100644 --- a/test/unit/specs/table.spec.js +++ b/test/unit/specs/table.spec.js @@ -611,6 +611,51 @@ describe('Table', () => { }, DELAY); }); + it('emit selection-change after row has been removed', done => { + const vm = createVue({ + template: ` + + + + + + + + `, + + created() { + this.testData = getTestData(); + }, + + data() { + return { selected: [], testData: null }; + }, + + methods: { + change(rows) { + this.selected = rows; + }, + + filterSelect(row, index) { + return index > 2; + } + } + }, true); + + setTimeout(_ => { + vm.$el.querySelector('.el-checkbox').click(); + setTimeout(_ => { + expect(vm.selected).to.length(5); + vm.testData.splice(0, 1); + setTimeout(_ => { + expect(vm.selected).to.length(4); + destroyVM(vm); + done(); + }); + }, DELAY); + }, DELAY); + }); + it('reserve-selection', done => { const getData = function(page = 0) { let id = 0;