Skip to content

Commit

Permalink
Merge branch 'template_based_view_refresh'
Browse files Browse the repository at this point in the history
Closes #7
  • Loading branch information
Spencer Alger committed Feb 25, 2014
2 parents 861ff58 + bdc13ef commit 96f3d3e
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
</li>
</ul>
</nav>
<div ng-view></div>
<div kbn-view></div>
</div>
</body>
</html>
6 changes: 6 additions & 0 deletions src/kibana/apps/examples/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ define(function (require) {
];

$scope.makeActive = function (example) {
$location.search({example: example});
$scope.active = example;
$scope.activeUrl = 'kibana/apps/examples/partials/' + example + '.html';
};
Expand All @@ -24,6 +25,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
Expand Down
121 changes: 121 additions & 0 deletions src/kibana/directives/kbn_view.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
define(function (require) {
var angular = require('angular');

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',
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() {
/****** START modification *******/
if ($route.current) {
if (currentTemplateUrl && $route.current.templateUrl === currentTemplateUrl) {
return;
} else {
currentTemplateUrl = $route.current.templateUrl;
}
}
/****** STOP modification *******/

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();
}
}
}
};
})

/******
****** 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',
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);
}
};
});

});
77 changes: 42 additions & 35 deletions src/kibana/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var scopedRequire = require('require');
var enableAsyncModules = require('utils/async_modules');
var setup = require('./setup');
var configFile = require('../config');

require('elasticsearch');
require('angular-route');

var kibana = angular.module('kibana', []);
enableAsyncModules(kibana);

var requiredAgularModules = [
var dependencies = [
'elasticsearch',
'ngRoute',
'kibana',
Expand All @@ -27,63 +29,68 @@ define(function (require) {
'kibana/constants'
];

requiredAgularModules.forEach(function (name) {
if (name.indexOf('kibana/') === 0) angular.module(name, []);
dependencies.forEach(function (name) {
if (name.indexOf('kibana/') === 0) {
kibana.useModule(angular.module(name, []));
}
});

kibana.requires = requiredAgularModules;
kibana.requires = dependencies;
kibana.value('configFile', configFile);

kibana.config(function ($routeProvider) {
$routeProvider
.otherwise({
redirectTo: '/' + configFile.defaultAppId
redirectTo: '/discover'
});

configFile.apps.forEach(function (app) {
var deps = {};
deps['app/' + app.id] = function () {
return kibana.loadChildApp(app);
};

$routeProvider.when('/' + app.id, {
templateUrl: '/kibana/apps/' + app.id + '/index.html'
templateUrl: '/kibana/apps/' + app.id + '/index.html',
resolve: deps
});
});
});

setup(kibana, function (err) {
if (err) throw err;
kibana.run(function ($q) {
kibana.loadChildApp = function (app) {
var defer = $q.defer();

// once all of the required modules are loaded, bootstrap angular
function bootstrap() {
$(function () {
angular.bootstrap(document, requiredAgularModules);
require([
'apps/' + app.id + '/index'
], function () {
defer.resolve();
delete require.onError;
});
}

// do some requirejs loading in parallel, otherwise we
// would have to track everything in the r.js optimization
// config
var out = 0;
function loaded() {
out ++;
return function () {
out--;
if (!out) {
// all of the callbacks have been called
bootstrap();
}
require.onError = function () {
defer.reject();
};
}

// require global modules
return defer.promise;
};
});

setup(kibana, function (err) {
if (err) throw err;

// load the elasticsearch service
require([
'controllers/kibana',
'directives/kbn_view',
'constants/base'
], loaded());

// require each applications root module
// since these are created via .map the same operation
// must be done in the r.js optimizer config
require(configFile.apps.map(function (app) {
return 'apps/' + app.id + '/index';
}), loaded());
], function () {
// bootstrap the app
$(function () {
angular
.bootstrap(document, dependencies);
});
});
});

return kibana;
Expand Down

0 comments on commit 96f3d3e

Please sign in to comment.