Extreme number of digests triggered by dataWatcher in uiGridCell
#6 436 ouverte le 26 oct. 2017
Métriques du dépôt
- Stars
- (5 395 stars)
- Métriques de merge PR
- (Aucune PR mergée en 30 j)
Description
Hi Guys,
I am experiencing a severe performance issue on updating data. I have localized it to this line of code in the uiGridCell directive
// Refresh cell focus when a new row id added to the grid
var dataChangeDereg = uiGridCtrl.grid.registerDataChangeCallback(function (grid) {
// Clear the focus if it's set to avoid the wrong cell getting focused during
// a short period of time (from now until $timeout function executed)
clearFocus();
$timeout(refreshCellFocus);
}, [uiGridConstants.dataChange.ROW]);
From what I can tell....when the dataWatcher is triggered, this callback is run for EVERY visible cell, simply to 'clear the focus for a short period of time'.
Each callback registers a new timeout...which in turn triggers a separate $apply...see below...from the AngularJS code as neither the delay, nor invokeApply is specified
function timeout(fn, delay, invokeApply) { if (!isFunction(fn)) { invokeApply = delay; delay = fn; fn = noop; }
var args = sliceArgs(arguments, 3),
skipApply = (isDefined(invokeApply) && !invokeApply),
deferred = (skipApply ? $$q : $q).defer(),
promise = deferred.promise,
timeoutId;
timeoutId = $browser.defer(function() {
try {
deferred.resolve(fn.apply(null, args));
} catch (e) {
deferred.reject(e);
$exceptionHandler(e);
}
finally {
delete deferreds[promise.$$timeoutId];
}
**if (!skipApply) $rootScope.$apply();**
}, delay);
resulting in one digest for every single visible cell. The result is several seconds to recover after every data update on a large table.

Am I missing something? Or, is there a better way to fix this focus issue?
I am attaching an image from my own scenario. The table has about 23 visible rows and 14ish columns (not sure...but the numbers add up to 300+ and I have tracked the timeouts as they are registered)
Any thoughts?
Cheers, Joel