Skip to content

Instantly share code, notes, and snippets.

@JimJafar
Last active December 17, 2015 09:19
Show Gist options
  • Save JimJafar/5586190 to your computer and use it in GitHub Desktop.
Save JimJafar/5586190 to your computer and use it in GitHub Desktop.
AngularJS allIncludeContentLoaded ngInclude extension demo
body {
font-family: Arial,Helvetica,sans-serif;
font-size: 14px;
margin: 0;
}
h4 {
font-size: 16px;
font-weight: bold;
}
#main, #first, #second, #console, #output1, #output2 {
border: 1px solid red;
margin: 10px;
padding: 10px;
}
#main {
border-color: blue;
}
#first, #second {
border-color: green;
}
<html ng-app="AllIncludeContentLoadedDemo">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/ng-template" id="first.html">
<p>This is the 1st nested template</p>
</script>
<script type="text/ng-template" id="second.html">
<p>This is the 2nd nested template</p>
</script>
<script type="text/ng-template" id="main.html">
<div id="main">
<p>This is the main template</p>
<div id="first" ng-include src="templates.first" ng-controller="FirstNestedCtrl"></div>
<div id="second" ng-include src="templates.second" ng-controller="SecondNestedCtrl"></div>
</div>
</script>
</head>
<body ng-controller="AppController">
<div ng-include src="templates.main" ng-controller="MainCtrl"></div>
<div id="console">
<h4>console log:</h4>
</div>
<div id="output1">
<h4>$includeContentLoaded events:</h4>
</div>
<div id="output2">
<h4>allIncludeContentLoaded events:</h4>
</div>
</body>
</html>
// Declare app level module which depends on filters, and services
var allIncludeContentLoadedDemo = angular.module('AllIncludeContentLoadedDemo', []);
/* Directives */
allIncludeContentLoadedDemo.directive('ngInclude', function() {
function recursivelyRegister(scopeToRegister, scopeToRegisterWith) {
if(!scopeToRegisterWith.hasOwnProperty('includesLoading')) {
scopeToRegisterWith.includesLoading = [];
}
if(scopeToRegisterWith.includesLoading.indexOf(scopeToRegister.$id) === -1) {
scopeToRegisterWith.includesLoading.push(scopeToRegister.$id);
if (scopeToRegister.hasOwnProperty('name') && scopeToRegisterWith.hasOwnProperty('name')) {
scopeToRegister.logToConsole(scopeToRegister.name + ' was linked under ' + scopeToRegisterWith.name);
}
}
if (scopeToRegisterWith.$parent) {
recursivelyRegister(scopeToRegister, scopeToRegisterWith.$parent);
}
}
function recursivelyDeRegisterAndNotify(scopeToDeRegister, scopeToDeRegisterFrom) {
var i = scopeToDeRegisterFrom.includesLoading.indexOf(scopeToDeRegister.$id);
if (i !== -1) {
scopeToDeRegisterFrom.includesLoading.splice(i, 1);
if (scopeToDeRegisterFrom.includesLoading.length === 0) {
if (scopeToDeRegisterFrom.hasOwnProperty('name')) {
scopeToDeRegister.logToConsole('all includes were loaded under ' + scopeToDeRegisterFrom.name);
}
scopeToDeRegisterFrom.$emit('allIncludesLoaded' + scopeToDeRegisterFrom.$id);
}
}
if (scopeToDeRegisterFrom.$parent) {
recursivelyDeRegisterAndNotify(scopeToDeRegister, scopeToDeRegisterFrom.$parent);
}
}
function recursivelyReset(scope) {
scope.includesLoading.length = 0;
if (scope.$parent) {
recursivelyReset(scope.$parent);
}
}
return {
restrict: 'A',
link: function(scope, element, attr, ngModel) {
recursivelyRegister(scope, scope.$parent);
scope.$on('$routeChangeSuccess', function() {
// empty the tracking arrays on route changes
recursivelyReset(scope);
});
scope.$on('$includeContentLoaded', function(event) {
if (scope.hasOwnProperty('name') && scope.$parent.hasOwnProperty('name')) {
scope.logToConsole(scope.name + ' was loaded under ' + scope.$parent.name);
}
recursivelyDeRegisterAndNotify(scope, scope.$parent);
});
}
};
});
/* App Controllers */
allIncludeContentLoadedDemo.controller('AppController', ['$rootScope','$route', '$location','$controller', function ($rootScope,$route,$location,$controller) {
$rootScope = angular.extend($rootScope, {
name : 'AppController',
templates : { main: 'main.html', first: 'first.html', second: 'second.html' },
registerAllIncludeContentLoadedListener : function(scope, listener) {
scope.$on('allIncludesLoaded' + scope.$id, listener);
},
logToConsole : function(message) {
$('#console').append('<p>' + message + '</p>');
console.log(message);
}
});
$rootScope.$on('$includeContentLoaded', function(event) {
$('#output1').append('<p>' + event.targetScope.name + ' include\'s content was loaded.</p>');
});
$rootScope.registerAllIncludeContentLoadedListener($rootScope, function() {
$('#output2').append('<p>All includes under AppController have been loaded.</p>');
});
}]);
allIncludeContentLoadedDemo.controller('MainCtrl', ['$scope', function ($scope) {
$scope.name = 'MainCtrl';
$scope.registerAllIncludeContentLoadedListener($scope, function() {
$('#output2').append('<p>All includes under MainCtrl have been loaded.</p>');
});
}]);
allIncludeContentLoadedDemo.controller('FirstNestedCtrl', ['$scope', function ($scope) {
$scope.name = 'FirstNestedCtrl';
}]);
allIncludeContentLoadedDemo.controller('SecondNestedCtrl', ['$scope', function ($scope) {
$scope.name = 'SecondNestedCtrl';
}]);
name: AngularJS allIncludeContentLoaded ngInclude extension demo
description: A jsFiddle of the directive in action with a load of debug info so you can see what's going on.
authors:
- Jim Sangwine
normalize_css: yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment