Skip to content

Commit bd10af8

Browse files
authored
fix(table): Only emit filtered event if filtered rows has changed. Fixes #1989
1 parent 5e5c5c9 commit bd10af8

File tree

1 file changed

+38
-17
lines changed

1 file changed

+38
-17
lines changed

src/components/table/table.js

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,29 @@ import listenOnRootMixin from '../../mixins/listen-on-root'
1313
// Import styles
1414
import './table.css'
1515

16-
// Object of item keys that should be ignored for headers and stringification
16+
// Object of item keys that should be ignored for headers and stringification and filter events
1717
const IGNORED_FIELD_KEYS = {
1818
_rowVariant: true,
1919
_cellVariants: true,
2020
_showDetails: true
2121
}
2222

23+
// Return a copy of a row after all reserved fields have been filtered out
24+
function sanitizeRow (row) {
25+
return keys(row).reduce((obj, key) => {
26+
// Ignore special fields that start with _
27+
if (!IGNORED_FIELD_KEYS[key]) {
28+
obj[k] = row[k]
29+
}
30+
return obj
31+
}, {})
32+
}
33+
34+
// Return a new array of records/rows that have been sanitized
35+
function sanitizeRows (rows) {
36+
return rows.map(row => sanitizeRow(row))
37+
}
38+
2339
// Stringifies the values of an object
2440
// { b: 3, c: { z: 'zzz', d: null, e: 2 }, d: [10, 12, 11], a: 'one' }
2541
// becomes
@@ -39,19 +55,11 @@ function toString (v) {
3955
}
4056

4157
// Stringifies the values of a record, ignoring any special top level keys
42-
function recToString (obj) {
58+
function recToString (row) {
4359
if (!(obj instanceof Object)) {
4460
return ''
4561
}
46-
return toString(
47-
keys(obj).reduce((o, k) => {
48-
// Ignore special fields that start with _
49-
if (!IGNORED_FIELD_KEYS[k]) {
50-
o[k] = obj[k]
51-
}
52-
return o
53-
}, {})
54-
)
62+
return toString(sanitizeRow(row))
5563
}
5664

5765
function defaultSortCompare (a, b, sortBy) {
@@ -413,8 +421,8 @@ export default {
413421
localSortBy: this.sortBy || '',
414422
localSortDesc: this.sortDesc || false,
415423
localItems: [],
416-
// Note: filteredItems only used to determine if # of items changed
417-
filteredItems: [],
424+
// Note: filteredItems only used to determine if items changed (set to null initially)
425+
filteredItems: null,
418426
localBusy: false
419427
}
420428
},
@@ -617,10 +625,23 @@ export default {
617625
this.$emit('context-changed', newVal)
618626
}
619627
},
620-
filteredItems (newVal, oldVal) {
621-
if (this.localFiltering && newVal.length !== oldVal.length) {
622-
// Emit a filtered notification event, as number of filtered items has changed
623-
this.$emit('filtered', newVal)
628+
filteredItems (newRows, oldRows) {
629+
if (!this.localFiltering || newRows === oldRows) {
630+
// If not local Filtering or nothing changed, don't emit a filtered event
631+
return
632+
}
633+
if (oldRows === null || newRows === null) {
634+
// If first run of updating items, don't emit a filtered event.
635+
return
636+
}
637+
// We compare lengths first for performance reasons, even though looseEqual
638+
// does this test, as we must sanitize the row data before passing it to
639+
// looseEqual, of which both could take time to run on long record sets!
640+
if (newRows.length !== oldRows.length ||
641+
!looseEqual(sanitizeRows(newRows), sanitizeRows(oldRows))) {
642+
// Emit a filtered notification event, as filtered items has changed
643+
// Note this may fire before the v-model has updated
644+
this.$emit('filtered', newRows)
624645
}
625646
},
626647
sortDesc (newVal, oldVal) {

0 commit comments

Comments
 (0)