[ML] Refactor to not rely on broadcast which could result in listeners not picking up changes. (#18717) (#18763)

Fixes an issue where the anomaly table wouldn't load because a broadcast to renderTable was triggered before the anomaly table directive initialized the corresponding listener. This change replaces the use of broadcast and instead uses $watch to listen on scope changes on the specific attributes relevant to the updates. The updating of code in parent scopes was moved inside the $timeouts instead of the broadcast event.
This commit is contained in:
Walter Rafelsberger 2018-05-03 11:49:26 +02:00 committed by GitHub
parent 88e269d35b
commit 78af9d7dc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 27 deletions

View file

@ -85,6 +85,7 @@ module.directive('mlAnomaliesTable', function (
scope.table.columns = [];
scope.table.rows = [];
scope.rowScopes = [];
scope.anomalyRecords = [];
scope.influencersLimit = 5;
@ -94,7 +95,7 @@ module.directive('mlAnomaliesTable', function (
mlSelectIntervalService.state.watch(updateTableData);
mlSelectSeverityService.state.watch(updateTableData);
scope.$on('renderTable', updateTableData);
scope.$watch('anomalyRecords', updateTableData);
element.on('$destroy', () => {
mlSelectIntervalService.state.unwatch(updateTableData);

View file

@ -171,13 +171,11 @@ module.controller('MlExplorerController', function (
jobIds, influencers, 0, earliestMs, latestMs, 500
)
.then((resp) => {
// Sort in descending time order before storing in scope.
$scope.anomalyRecords = _.chain(resp.records).sortBy(record => record[$scope.timeFieldName]).reverse().value();
console.log('Explorer anomalies table data set:', $scope.anomalyRecords);
// Need to use $timeout to ensure the broadcast happens after the child scope is updated with the new data.
// Need to use $timeout to ensure the update happens after the child scope is updated with the new data.
$timeout(() => {
$scope.$broadcast('renderTable');
// Sort in descending time order before storing in scope.
$scope.anomalyRecords = _.chain(resp.records).sortBy(record => record[$scope.timeFieldName]).reverse().value();
console.log('Explorer anomalies table data set:', $scope.anomalyRecords);
}, 0);
});
};

View file

@ -115,9 +115,9 @@ module.directive('mlTimeseriesChart', function (
drawContextChartSelection();
});
scope.$on('renderFocusChart', () => {
renderFocusChart();
});
scope.$watch('focusChartData', renderFocusChart);
scope.$watch('showModelBounds', renderFocusChart);
scope.$watch('showForecast', renderFocusChart);
// Redraw the charts when the container is resize.
const resizeChecker = new ResizeChecker(angular.element('.ml-timeseries-chart'));

View file

@ -360,22 +360,19 @@ module.controller('MlTimeSeriesExplorerController', function (
function finish() {
awaitingCount--;
if (awaitingCount === 0) {
processDataForFocusAnomalies(
$scope.focusChartData,
$scope.anomalyRecords,
$scope.timeFieldName);
processScheduledEventsForChart(
$scope.focusChartData,
$scope.scheduledEvents);
console.log('Time series explorer focus chart data set:', $scope.focusChartData);
// Tell the results container directives to render the focus chart.
// Need to use $timeout to ensure the broadcast happens after the child scope is updated with the new data.
$timeout(() => {
$scope.$broadcast('renderFocusChart');
$scope.$broadcast('renderTable');
processDataForFocusAnomalies(
$scope.focusChartData,
$scope.anomalyRecords,
$scope.timeFieldName);
processScheduledEventsForChart(
$scope.focusChartData,
$scope.scheduledEvents);
console.log('Time series explorer focus chart data set:', $scope.focusChartData);
$scope.loading = false;
}, 0);
@ -559,16 +556,14 @@ module.controller('MlTimeSeriesExplorerController', function (
};
$scope.toggleShowModelBounds = function () {
$scope.showModelBounds = !$scope.showModelBounds;
$timeout(() => {
$scope.$broadcast('renderFocusChart');
$scope.showModelBounds = !$scope.showModelBounds;
}, 0);
};
$scope.toggleShowForecast = function () {
$scope.showForecast = !$scope.showForecast;
$timeout(() => {
$scope.$broadcast('renderFocusChart');
$scope.showForecast = !$scope.showForecast;
}, 0);
};