Skip to content

Commit

Permalink
fix: content inside the oc-lazy-load directive is now compiled on load
Browse files Browse the repository at this point in the history
Fixes #80
  • Loading branch information
ocombe committed Nov 9, 2014
1 parent 11b5ffa commit 9962e2e
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 346 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,15 @@ $ocLazyLoad.load({
```

### Directive
The directive is very similar to the service. Use the same parameters:
The directive usage is very similar to the service. The main interest here is that the content will be included and compiled once your modules have been loaded.
This means that you can use directives that will be lazy loaded inside the oc-lazy-load directive.

Use the same parameters than the service:
```html
<div oc-lazy-load="{name: 'TestModule', files: ['js/testModule.js', 'partials/lazyLoadTemplate.html']}"></div>
<div oc-lazy-load="{name: 'TestModule', files: ['js/testModule.js', 'partials/lazyLoadTemplate.html']}">
// Use a directive from TestModule
<test-directive></test-directive>
</div>
```

You can use variables to store parameters:
Expand Down
66 changes: 14 additions & 52 deletions dist/ocLazyLoad.js
Original file line number Diff line number Diff line change
Expand Up @@ -588,69 +588,31 @@
};
}]);

ocLazyLoad.directive('ocLazyLoad', ['$http', '$log', '$ocLazyLoad', '$compile', '$timeout', '$templateCache', '$animate',
function($http, $log, $ocLazyLoad, $compile, $timeout, $templateCache, $animate) {
ocLazyLoad.directive('ocLazyLoad', ['$ocLazyLoad', '$compile', '$animate', '$parse',
function($ocLazyLoad, $compile, $animate, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 401, // 1 more than ngInclude
transclude: 'element',
controller: angular.noop,
priority: 1000,
compile: function(element, attrs) {
return function($scope, $element, $attr, ctrl, $transclude) {
var childScope,
evaluated = $scope.$eval($attr.ocLazyLoad),
onloadExp = evaluated && evaluated.onload ? evaluated.onload : '';

/**
* Destroy the current scope of this element and empty the html
*/
function clearContent() {
if(childScope) {
childScope.$destroy();
childScope = null;
}
$element.html('');
}

/**
* Load a template from cache or url
* @param url
* @param callback
*/
function loadTemplate(url, callback) {
var view;

if(typeof(view = $templateCache.get(url)) !== 'undefined') {
callback(view);
} else {
$http.get(url)
.success(function(data) {
$templateCache.put('view:' + url, data);
callback(data);
})
.error(function(data) {
$log.error('Error load template "' + url + '": ' + data);
});
}
}

$scope.$watch($attr.ocLazyLoad, function(moduleName) {
// we store the content and remove it before compilation
var content = element[0].innerHTML;
element.html('');

return function($scope, $element, $attr) {
var model = $parse($attr.ocLazyLoad);
$scope.$watch(function() {
// it can be a module name (string), an object, an array, or a scope reference to any of this
return model($scope) || $attr.ocLazyLoad;
}, function(moduleName) {
if(angular.isDefined(moduleName)) {
$ocLazyLoad.load(moduleName).then(function(moduleConfig) {
$transclude($scope, function cloneConnectFn(clone) {
$animate.enter(clone, null, $element);
});
$animate.enter($compile(content)($scope), null, $element);
});
} else {
clearContent();
}
}, true);
};
}
/*link: function($scope, $element, $attr) {
}*/
};
}]);

Expand Down
2 changes: 1 addition & 1 deletion dist/ocLazyLoad.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/example1/index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en" xmlns:ng="http://angularjs.org" id="ng-app" ng-app="app">
<html lang="en" xmlns:ng="http://angularjs.org" ng-app="app">
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
Expand All @@ -23,4 +23,4 @@ <h1 class="page-header">$ocLazyLoad</h1>
</p>
<div ui-view="lazyLoadView"></div>
</body>
</html>
</html>
72 changes: 34 additions & 38 deletions examples/example1/js/AppCtrl.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,35 @@
angular.module('app').controller('AppCtrl', ['$scope', '$ocLazyLoad', '$timeout', function($scope, $ocLazyLoad, $timeout) {
$scope.$on('ocLazyLoad.moduleLoaded', function(e, params) {
console.log('event module loaded', params);
});
$scope.$on('ocLazyLoad.componentLoaded', function(e, params) {
console.log('event component loaded', params);
});
$scope.$on('ocLazyLoad.fileLoaded', function(e, file) {
console.log('event file loaded', file);
});
$scope.loadBootstrap = function() {
var unbind = $scope.$on('ocLazyLoad.fileLoaded', function(e, file) {
if(file === 'bower_components/bootstrap/dist/css/bootstrap.css') {
$scope.bootstrapLoaded = true;
unbind();
}
});
$scope.bootstrapModule = [
'bower_components/bootstrap/dist/js/bootstrap.js',
'bower_components/bootstrap/dist/css/bootstrap.css'
];
}
angular.module('app').controller('AppCtrl', function($scope, $ocLazyLoad) {
$scope.$on('ocLazyLoad.moduleLoaded', function(e, params) {
console.log('event module loaded', params);
});
$scope.$on('ocLazyLoad.componentLoaded', function(e, params) {
console.log('event component loaded', params);
});
$scope.$on('ocLazyLoad.fileLoaded', function(e, file) {
console.log('event file loaded', file);
});
$scope.loadBootstrap = function() {
// use events to know when the files are loaded
var unbind = $scope.$on('ocLazyLoad.fileLoaded', function(e, file) {
if(file === 'bower_components/bootstrap/dist/css/bootstrap.css') {
$scope.bootstrapLoaded = true;
unbind();
}
});
// we could use .then here instead of events
$ocLazyLoad.load([
'bower_components/bootstrap/dist/js/bootstrap.js',
'bower_components/bootstrap/dist/css/bootstrap.css'
]);
}

$scope.loadGridModule = function() {
$ocLazyLoad.load({
name: 'gridModule',
files: [
'js/gridModule.js',
'partials/grid.html'
]
}).then(function success(data) {
console.log('loaded', data);
$scope.gridInclude = 'gridTemplate';
$scope.gridLoaded = true;
}, function error(err) {
console.log(err);
});
}
}])
$scope.loadGridModule = function() {
$ocLazyLoad.load().then(function success(data) {
console.log('loaded', data);
$scope.gridInclude = 'gridTemplate';
$scope.gridLoaded = true;
}, function error(err) {
console.log(err);
});
}
})
142 changes: 73 additions & 69 deletions examples/example1/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,75 +2,79 @@

// Declare app level module which depends on filters, and services
var App = angular.module('app', ['ui.router', 'oc.lazyLoad'])
.config(['$stateProvider', '$locationProvider', '$urlRouterProvider', function($stateProvider, $locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$locationProvider.hashPrefix('!');
.config(function($stateProvider, $locationProvider, $urlRouterProvider, $ocLazyLoadProvider) {
$urlRouterProvider.otherwise("/");
$locationProvider.hashPrefix('!');

// You can also load via resolve
$stateProvider
.state('index', {
url: "/", // root route
views: {
"lazyLoadView": {
controller: 'AppCtrl', // This view will use AppCtrl loaded below in the resolve
templateUrl: 'partials/main.html'
}
},
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load({
name: 'app',
files: ['js/AppCtrl.js']
});
}]
}
})
.state('modal', {
parent: 'index',
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadOcModal: ['$ocLazyLoad', '$injector', '$rootScope', function($ocLazyLoad, $injector, $rootScope) {
// Load 'oc.modal' defined in the config of the provider $ocLazyLoadProvider
return $ocLazyLoad.load('oc.modal').then(function() {
$rootScope.bootstrapLoaded = true;
// inject the lazy loaded service
var $ocModal = $injector.get("$ocModal");
$ocModal.open({
url: 'modal',
cls: 'fade-in'
});
});
}],
// You can also load via resolve
$stateProvider
.state('index', {
url: "/", // root route
views: {
"lazyLoadView": {
controller: 'AppCtrl', // This view will use AppCtrl loaded below in the resolve
templateUrl: 'partials/main.html'
}
},
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadMyCtrl: ['$ocLazyLoad', function($ocLazyLoad) {
// you can lazy load files for an existing module
return $ocLazyLoad.load({
name: 'app',
files: ['js/AppCtrl.js']
});
}]
}
})
.state('modal', {
parent: 'index',
resolve: { // Any property in resolve should return a promise and is executed before the view is loaded
loadOcModal: ['$ocLazyLoad', '$injector', '$rootScope', function($ocLazyLoad, $injector, $rootScope) {
// Load 'oc.modal' defined in the config of the provider $ocLazyLoadProvider
return $ocLazyLoad.load({
name: 'oc.modal',
files: [
'bower_components/bootstrap/dist/css/bootstrap.css', // will use the cached version if you already loaded bootstrap with the button
'bower_components/ocModal/dist/css/ocModal.animations.css',
'bower_components/ocModal/dist/css/ocModal.light.css',
'bower_components/ocModal/dist/ocModal.js',
'partials/modal.html'
]
}).then(function() {
$rootScope.bootstrapLoaded = true;
// inject the lazy loaded service
var $ocModal = $injector.get("$ocModal");
$ocModal.open({
url: 'modal',
cls: 'fade-in'
});
});
}],

// resolve the sibling state and use the service lazy loaded
setModalBtn: ['loadOcModal', '$rootScope', '$ocModal', function(loadOcModal, $rootScope, $ocModal) {
$rootScope.openModal = function() {
$ocModal.open({
url: 'modal',
cls: 'flip-vertical'
});
}
}]
}
});
// resolve the sibling state and use the service lazy loaded
setModalBtn: ['loadOcModal', '$rootScope', '$ocModal', function(loadOcModal, $rootScope, $ocModal) {
$rootScope.openModal = function() {
$ocModal.open({
url: 'modal',
cls: 'flip-vertical'
});
}
}]
}
});

// Without server side support html5 must be disabled.
return $locationProvider.html5Mode(false);
}])
.config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
// We configure ocLazyLoad to use the lib script.js as the async loader
$ocLazyLoadProvider.config({
debug: true,
events: true,
modules: [{
name: 'oc.modal',
files: [
'bower_components/bootstrap/dist/css/bootstrap.css', // will use the cached version if you already loaded bootstrap with the button
'bower_components/ocModal/dist/css/ocModal.animations.css',
'bower_components/ocModal/dist/css/ocModal.light.css',
'bower_components/ocModal/dist/ocModal.js',
'partials/modal.html'
]
}]
});
}]);
// Without server side support html5 must be disabled.
$locationProvider.html5Mode(false);

// We configure ocLazyLoad to use the lib script.js as the async loader
$ocLazyLoadProvider.config({
debug: true,
events: true,
modules: [{
name: 'gridModule',
files: [
'js/gridModule.js'
]
}]
});
});
33 changes: 18 additions & 15 deletions examples/example1/js/gridModule.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
// ngGrid is also lazy loaded by $ocLazyLoad thanks to the module dependency injection !
angular.module('gridModule', [{name: 'ui.grid.rowEdit', files: [
'bower_components/angular-ui-grid/ui-grid.js',
'bower_components/angular-ui-grid/ui-grid.css'
]}]).controller('GridModuleCtrl', ['$scope', function($scope){
$scope.myData = [{name: "Moroni", age: 50},
{name: "Teancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.gridOptions = { data: 'myData' };
}]).config(function() {
console.warn('config gridModule');
angular.module('gridModule', [{
name: 'ui.grid.rowEdit', files: [
'bower_components/angular-ui-grid/ui-grid.js',
'bower_components/angular-ui-grid/ui-grid.css'
]
}]).controller('GridModuleCtrl', function($scope) {
console.log('------- grid module ctrl');
$scope.myData = [{name: "Moroni", age: 50},
{name: "Teancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.gridOptions = {data: 'myData'};
}).config(function() {
console.warn('config gridModule');
}).config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
console.warn('config 2 gridModule');
console.warn('config 2 gridModule');
}]).run(function() {
console.warn('run gridModule');
});
console.warn('run gridModule');
});
Loading

0 comments on commit 9962e2e

Please sign in to comment.