From c54eb3f32729dd188a3fdb7326cedb9970adca8b Mon Sep 17 00:00:00 2001 From: Stacey Gammon Date: Wed, 30 Nov 2016 15:55:28 -0500 Subject: [PATCH] make scope isolate --- .../dashboard/components/panel/panel.js | 85 +++++++++---------- .../public/dashboard/directives/grid.js | 31 +++++-- 2 files changed, 62 insertions(+), 54 deletions(-) diff --git a/src/core_plugins/kibana/public/dashboard/components/panel/panel.js b/src/core_plugins/kibana/public/dashboard/components/panel/panel.js index 776f1f04fbcb9..7477a98d3f6f8 100644 --- a/src/core_plugins/kibana/public/dashboard/components/panel/panel.js +++ b/src/core_plugins/kibana/public/dashboard/components/panel/panel.js @@ -27,60 +27,55 @@ uiModules return { restrict: 'E', template: panelTemplate, - requires: '^dashboardGrid', + scope: { + chrome: '=', + parentUiState: '=', + panel: '=', + remove: '&' + }, link: function ($scope) { - // using $scope inheritance, panels are available in AppState - const $state = $scope.state; - // receives $scope.panel from the dashboard grid directive, seems like should be isolate? - $scope.$watch('id', function () { - if (!$scope.panel.id || !$scope.panel.type) return; + if (!$scope.panel.id || !$scope.panel.type) return; - loadPanel($scope.panel, $scope) - .then(function (panelConfig) { - // These could be done in loadPanel, putting them here to make them more explicit - $scope.savedObj = panelConfig.savedObj; - $scope.editUrl = panelConfig.editUrl; - $scope.$on('$destroy', function () { - panelConfig.savedObj.destroy(); - $scope.parentUiState.removeChild(getPanelId(panelConfig.panel)); - }); - - // create child ui state from the savedObj - const uiState = panelConfig.uiState || {}; - $scope.uiState = $scope.parentUiState.createChild(getPanelId(panelConfig.panel), uiState, true); - const panelSavedVis = _.get(panelConfig, 'savedObj.vis'); // Sometimes this will be a search, and undef - if (panelSavedVis) { - panelSavedVis.setUiState($scope.uiState); - } + loadPanel($scope.panel, $scope) + .then(function (panelConfig) { + // These could be done in loadPanel, putting them here to make them more explicit + $scope.savedObj = panelConfig.savedObj; + $scope.editUrl = panelConfig.editUrl; + $scope.$on('$destroy', function () { + panelConfig.savedObj.destroy(); + $scope.parentUiState.removeChild(getPanelId(panelConfig.panel)); + }); - $scope.filter = function (field, value, operator) { - const index = $scope.savedObj.searchSource.get('index').id; - filterManager.add(field, value, operator, index); - }; - }) - .catch(function (e) { - $scope.error = e.message; + // create child ui state from the savedObj + const uiState = panelConfig.uiState || {}; + $scope.uiState = $scope.parentUiState.createChild(getPanelId(panelConfig.panel), uiState, true); + const panelSavedVis = _.get(panelConfig, 'savedObj.vis'); // Sometimes this will be a search, and undef + if (panelSavedVis) { + panelSavedVis.setUiState($scope.uiState); + } - // If the savedObjectType matches the panel type, this means the object itself has been deleted, - // so we shouldn't even have an edit link. If they don't match, it means something else is wrong - // with the object (but the object still exists), so we link to the object editor instead. - const objectItselfDeleted = e.savedObjectType === $scope.panel.type; - if (objectItselfDeleted) return; + $scope.filter = function (field, value, operator) { + const index = $scope.savedObj.searchSource.get('index').id; + filterManager.add(field, value, operator, index); + }; + }) + .catch(function (e) { + $scope.error = e.message; - const type = $scope.panel.type; - const id = $scope.panel.id; - const service = _.find(services, { type: type }); - if (!service) return; + // If the savedObjectType matches the panel type, this means the object itself has been deleted, + // so we shouldn't even have an edit link. If they don't match, it means something else is wrong + // with the object (but the object still exists), so we link to the object editor instead. + const objectItselfDeleted = e.savedObjectType === $scope.panel.type; + if (objectItselfDeleted) return; - $scope.editUrl = '#management/kibana/objects/' + service.name + '/' + id + '?notFound=' + e.savedObjectType; - }); + const type = $scope.panel.type; + const id = $scope.panel.id; + const service = _.find(services, { type: type }); + if (!service) return; + $scope.editUrl = '#management/kibana/objects/' + service.name + '/' + id + '?notFound=' + e.savedObjectType; }); - - $scope.remove = function () { - _.pull($state.panels, $scope.panel); - }; } }; }); diff --git a/src/core_plugins/kibana/public/dashboard/directives/grid.js b/src/core_plugins/kibana/public/dashboard/directives/grid.js index 7b744ba9a1572..29ebf24f656cb 100644 --- a/src/core_plugins/kibana/public/dashboard/directives/grid.js +++ b/src/core_plugins/kibana/public/dashboard/directives/grid.js @@ -73,6 +73,12 @@ app.directive('dashboardGrid', function ($compile, Notifier) { gridster.enable().enable_resize(); }); + // Does not remove the panel from the ui - that will be handled by the watch below, which + // will be triggered by the removal. + $scope.removePanelFromState = (panel) => { + _.pull($scope.state.panels, panel); + }; + $scope.$watchCollection('state.panels', function (panels) { const currentPanels = gridster.$widgets.toArray().map(function (el) { return getPanelFor(el); @@ -126,7 +132,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { const panel = $panel.data('panel'); panel.$el = $panel; - panel.$scope = $panel.data('$scope'); + // panel.$scope = $panel.data('$scope'); return panel; } @@ -136,7 +142,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { // want them to show up in the url) function makePanelSerializeable(panel) { delete panel.$el; - delete panel.$scope; + // delete panel.$scope; } // tell gridster to remove the panel, and cleanup our metadata @@ -145,7 +151,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { gridster.remove_widget(panel.$el, silent); // destroy the scope - panel.$scope.$destroy(); + // panel.$scope.$destroy(); panel.$el.removeData('panel'); panel.$el.removeData('$scope'); @@ -170,11 +176,19 @@ app.directive('dashboardGrid', function ($compile, Notifier) { } } - panel.$scope = $scope.$new(); - panel.$scope.panel = panel; - panel.$scope.parentUiState = $scope.uiState; + // panel.$scope = $scope.$new(); + // panel.$scope.panel = panel; + // panel.$scope.parentUiState = $scope.uiState; + const panelIndex = _.indexOf($scope.state.panels, panel); - panel.$el = $compile('
  • ')(panel.$scope); + const panelHtml = ` +
  • + +
  • `; + panel.$el = $compile(panelHtml)($scope); // tell gridster to use the widget gridster.add_widget(panel.$el, panel.size_x, panel.size_y, panel.col, panel.row); @@ -184,7 +198,7 @@ app.directive('dashboardGrid', function ($compile, Notifier) { // stash the panel and it's scope in the element's data panel.$el.data('panel', panel); - panel.$el.data('$scope', panel.$scope); + // panel.$el.data('$scope', panel.$scope); } // ensure that the panel object has the latest size/pos info @@ -202,7 +216,6 @@ app.directive('dashboardGrid', function ($compile, Notifier) { gridster.$widgets.each(function (i, el) { const panel = getPanelFor(el); refreshPanelStats(panel); - panel.$scope.$broadcast('resize'); makePanelSerializeable(panel); $scope.$root.$broadcast('change:vis'); });