From 34c7272bad738a0aa870b16bc7fe8d7cf686c256 Mon Sep 17 00:00:00 2001 From: Spencer Alger Date: Mon, 24 Feb 2014 16:47:53 -0700 Subject: [PATCH 1/2] Only refresh a view when the template changes. The ngView directive was cloned and modified to accomplish this --- src/index.html | 2 +- src/kibana/apps/examples/index.js | 6 ++ src/kibana/directives/kbn_view.js | 103 ++++++++++++++++++++++++++++++ src/kibana/{main.js => index.js} | 1 + src/kibana/require.config.js | 2 +- 5 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 src/kibana/directives/kbn_view.js rename src/kibana/{main.js => index.js} (98%) diff --git a/src/index.html b/src/index.html index e6b71b7e5eb74..85f0f1070df12 100644 --- a/src/index.html +++ b/src/index.html @@ -21,7 +21,7 @@ -
+
diff --git a/src/kibana/apps/examples/index.js b/src/kibana/apps/examples/index.js index 0158ac66045e2..6271ab47cf47a 100644 --- a/src/kibana/apps/examples/index.js +++ b/src/kibana/apps/examples/index.js @@ -16,6 +16,7 @@ define(function (require) { ]; $scope.makeActive = function (example) { + $location.search({example: example}); $scope.active = example; $scope.activeUrl = 'kibana/apps/examples/partials/' + example + '.html'; }; @@ -25,6 +26,11 @@ define(function (require) { courier.fetch(); } }; + + var initial = $location.search().example; + if (initial) { + $scope.makeActive(initial); + } }); // verify that config can be used, that it is stored, and that changes to it can be seen across tabs diff --git a/src/kibana/directives/kbn_view.js b/src/kibana/directives/kbn_view.js new file mode 100644 index 0000000000000..5a753477efdca --- /dev/null +++ b/src/kibana/directives/kbn_view.js @@ -0,0 +1,103 @@ +define(function (require) { + var angular = require('angular'); + + angular + .module('kibana/directives') + .directive('kbnView', function modifiedNgViewFactory($route, $anchorScroll, $animate) { + return { + restrict: 'ECA', + terminal: true, + priority: 400, + transclude: 'element', + link: function (scope, $element, attr, ctrl, $transclude) { + var currentScope; + var currentElement; + var currentTemplateUrl; + var autoScrollExp = attr.autoscroll; + var onloadExp = attr.onload || ''; + + scope.$on('$routeChangeSuccess', update); + update(); + + function cleanupLastView() { + if (currentScope) { + currentScope.$destroy(); + currentScope = null; + } + if (currentElement) { + $animate.leave(currentElement); + currentElement = null; + } + } + + function update() { + if ($route.current) { + if (currentTemplateUrl && $route.current.templateUrl === currentTemplateUrl) { + return; + } else { + currentTemplateUrl = $route.current.templateUrl; + } + } + + var locals = $route.current && $route.current.locals; + var template = locals && locals.$template; + + if (angular.isDefined(template)) { + var newScope = scope.$new(); + var current = $route.current; + + // Note: This will also link all children of ng-view that were contained in the original + // html. If that content contains controllers, ... they could pollute/change the scope. + // However, using ng-view on an element with additional content does not make sense... + // Note: We can't remove them in the cloneAttchFn of $transclude as that + // function is called before linking the content, which would apply child + // directives to non existing elements. + var clone = $transclude(newScope, function (clone) { + $animate.enter(clone, null, currentElement || $element, function onNgViewEnter() { + if (angular.isDefined(autoScrollExp) + && (!autoScrollExp || scope.$eval(autoScrollExp))) { + $anchorScroll(); + } + }); + cleanupLastView(); + }); + + currentElement = clone; + currentScope = current.scope = newScope; + currentScope.$emit('$viewContentLoaded'); + currentScope.$eval(onloadExp); + } else { + cleanupLastView(); + } + } + } + }; + }) + .directive('kbnView', function modifiedNgViewFillContentFactory($compile, $controller, $route) { + return { + restrict: 'ECA', + priority: -400, + link: function (scope, $element) { + var current = $route.current, + locals = current.locals; + + $element.html(locals.$template); + + var link = $compile($element.contents()); + + if (current.controller) { + locals.$scope = scope; + var controller = $controller(current.controller, locals); + if (current.controllerAs) { + scope[current.controllerAs] = controller; + } + $element.data('$ngControllerController', controller); + $element.children().data('$ngControllerController', controller); + } + + link(scope); + } + }; + }); + +}); \ No newline at end of file diff --git a/src/kibana/main.js b/src/kibana/index.js similarity index 98% rename from src/kibana/main.js rename to src/kibana/index.js index ed4c752baa2e2..a6e49e01b1e94 100644 --- a/src/kibana/main.js +++ b/src/kibana/index.js @@ -82,6 +82,7 @@ define(function (require) { // load the elasticsearch service require([ 'controllers/kibana', + 'directives/kbn_view', 'constants/base' ], function () { // bootstrap the app diff --git a/src/kibana/require.config.js b/src/kibana/require.config.js index abcab000aaee9..eaf685c0939d9 100644 --- a/src/kibana/require.config.js +++ b/src/kibana/require.config.js @@ -1,7 +1,7 @@ require.config({ baseUrl: 'kibana', paths: { - kibana: './main', + kibana: './index', courier: '../courier', angular: '../bower_components/angular/angular', 'angular-route': '../bower_components/angular-route/angular-route', From 642d492597580e0d2a5f03d260e5cdc53be1ec12 Mon Sep 17 00:00:00 2001 From: Spencer Alger Date: Tue, 25 Feb 2014 09:07:40 -0700 Subject: [PATCH 2/2] added comments that explicitly label the modified section, and detail where to find the original code so that we can maintain some parity down the road --- src/kibana/directives/kbn_view.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/kibana/directives/kbn_view.js b/src/kibana/directives/kbn_view.js index 5a753477efdca..eae3f211c9358 100644 --- a/src/kibana/directives/kbn_view.js +++ b/src/kibana/directives/kbn_view.js @@ -3,6 +3,14 @@ define(function (require) { angular .module('kibana/directives') + /****** + ****** COPIED directive from angular-router + ****** https://github.com/angular/angular.js/blob/6f0503514f/src/ngRoute/directive/ngView.js#L183 + ****** + ****** Modification made: + ****** - prevent the view from being recreated unnecessarily + ****** + ******/ .directive('kbnView', function modifiedNgViewFactory($route, $anchorScroll, $animate) { return { restrict: 'ECA', @@ -31,6 +39,7 @@ define(function (require) { } function update() { + /****** START modification *******/ if ($route.current) { if (currentTemplateUrl && $route.current.templateUrl === currentTemplateUrl) { return; @@ -38,6 +47,7 @@ define(function (require) { currentTemplateUrl = $route.current.templateUrl; } } + /****** STOP modification *******/ var locals = $route.current && $route.current.locals; var template = locals && locals.$template; @@ -73,6 +83,14 @@ define(function (require) { } }; }) + + /****** + ****** COPIED directive from angular-router + ****** https://github.com/angular/angular.js/blob/6f0503514f/src/ngRoute/directive/ngView.js#L251 + ****** + ****** No Modifications made + ****** + ******/ .directive('kbnView', function modifiedNgViewFillContentFactory($compile, $controller, $route) { return { restrict: 'ECA',