AngularJS Initialization Demo (with init)
Demonstrate an initialization service to compensate early $watch or $on triggers during the application bootstrap. See http://wp.me/p1E7sK-hn for explanation.
by manoj
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.5/angular.min.js"></script>
<div ng-app="myModule" class="wrapper">
<h2>AngularJS Initialization Demo</h2>
<p>For details see <a href="http://wp.me/p1E7sK-hn" target="_blank">article</a>
<div ng-controller="simpleController" class="left">
<h3>basic example</h3>
<p ng-show="options.length == 0">loading options...</p>
<select ng-show="options.length !== 0"
ng-model="selectedOption"
ng-options="option.value as option.name for option in options">
</select>
<div class="log">
log:
<ul>
<li ng-repeat="entry in logentries">{{entry}}</li>
</ul>
</div>
</div>
<div ng-controller="controllerWithInitialization" class="right">
<h3>initialization aware</h3>
<p ng-show="options.length == 0">loading options...</p>
<select ng-show="options.length !== 0"
ng-model="selectedOption"
ng-options="option.value as option.name for option in options">
</select>
<div class="log">
log:
<ul>
<li ng-repeat="entry in logentries">{{entry}}</li>
</ul>
</div>
</div>
</div>
CSS
div.left,
div.right {
position: relative;
float: left;
}
.wrapper {
width: 100%;
}
.left {
width: 40%;
}
.right {
width: 40%;
}
.log {
margin-top: 10px;
}
ul {
list-style-type: none;
}
JavaScript
var myModule = angular.module('myModule', []);
myModule.factory('init', function ($q, $rootScope, $browser) {
var initFunctions = [
'controllerWithInitialization'
];
var registeredInitFunctions = {};
var initialized = false;
var initApplication = function () {
var controllerWithInitialization = registeredInitFunctions['controllerWithInitialization'];
var broadcastAppInitialized = function () {
$browser.defer(function () {
initialized = true;
$rootScope.$apply(function () {
$rootScope.$broadcast('appInitialized');
});
});
};
controllerWithInitialization.init()
.then(broadcastAppInitialized);
};
$rootScope.$on('$routeChangeStart', function () {
registeredInitFunctions = {};
initialized = false;
});
var initAppWhenReady = function () {
var registeredInitFunctionNames = _.keys(registeredInitFunctions);
var isRegistered = _.partial(_.contains, registeredInitFunctionNames);
if (_.every(initFunctions, isRegistered)) {
initApplication();
registeredInitFunctions = null;
}
};
var init = function (name, dependencies, initCallback) {
registeredInitFunctions[name] = {
init: function () {
var internalDependencies = $q.all(dependencies);
return internalDependencies.then(initCallback);
}};
initAppWhenReady();
};
init.watchAfterInit = function (scope, expression, listener, deepEqual) {
scope.$watch(expression, function (newValue, oldValue, listenerScope) {
if (initialized) {
listener(newValue, oldValue, listenerScope);
}
}, deepEqual);
};
init.onAfterInit = function (scope, event, listener) {
scope.$on(event, function (event) {
if (initialized) {
listener(event);
}
});
};
return init;
});
myModule.service('myService', function($http) {
$http.defaults.headers.post['Content-Type'] =...