A presentation made for the AngularJS-IL meetup group that took place in jan 2014 at Google TLV Campus.
its a demonstration of how to integrate requireJS with AngularJS to achieve lazy loading and registration of angular components after bootstrap.
this slideshow contain a link for a working demo
3. overview
AngularJS encourage us to break our code
into smaller pieces.
Modules
services
directives
controllers
filters
constants
nirkaufman@gmail.com
4. overview
Separating your code into multiple files considered
a best practice when building large apps with
angular.
Angular seed project:
❖
js/
angular.module('myApp.controllers', []).
■
■
■
■
❖
controllers.js
services.js
directives.js
filters.js
partials/
■ partial1.html
■ partial2.html
controller('MyCtrl1', function() {
})
.controller('MyCtrl2', function() {
});
nirkaufman@gmail.com
5. overview
We can define our modules as dependencies:
angular.module('myApp',['ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers',
’ngRoute’,
’ngResource’,
’ui.bootstrap’,
]).
nirkaufman@gmail.com
6. overview
but we must load all of our resources ahead:
<script src="lib/angular.js"></script>
<script src="lib/angular-route.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
………………..
<script src="lib/angular-resource.js"></script>
<script src="lib/angular-bootstrap.js"></script>
<script src="lib/underscore.js"></script>
nirkaufman@gmail.com
7. overview
All components must register against our module
on bootstrap. otherwise we can't use them.
Error: Argument ‘myController’ is not a function, got undefined
register
Lazy Loading Angular components
nirkaufman@gmail.com
8. solution
We need to answer those 3 questions in order to
solve this challenge:
● How to lazy load scripts async ?
● How to register our components against
our module after bootstrap?
● When & where the actual loading occurs?
nirkaufman@gmail.com
9. loading
RequireJS provides a clean way to load and
manage dependencies for our applications.
<script data-main="main" src="require.js"></script>
define(function () {
// module code
})
require([‘module’], function (module) {
// use this module
})
http://requirejs.org/
nirkaufman@gmail.com
10. register
Components register against the module in the
config phase using providers.
For instance, we can register our controller
manually using the ‘$controllerProvider’:
angular.module('moduleName', [])
.config(function($controllerProvider) {
$controllerProvider.register('Ctrl', function () {
// controller code
})
});
nirkaufman@gmail.com
11. register
All components can be registered with their
matching provider methods:
// services can register with $provide
$provide.service()
$provide.factory(),
$provide.value(),
$provide.constant(),
// other components use specific providers
$controllerProvider.resgister()
$animateProvider.resgister()
$filterProvider.resgister()
$compileProvider.directive()
nirkaufman@gmail.com
12. register
we need to hold a reference to this provider in
order to use it later in our code:
var app = angular.module('moduleName', [])
.config(function($controllerProvider) {
app.loadController = $controllerProvider.register;
})
});
app.loadController(‘someCtrl’, function ($scope) {})
nirkaufman@gmail.com
13. when to load
Where in the application should the actual loading
take place?
● when routing to a view - $routeProvider
● when loading content - <ng-include>
● in response to event - like click or hover
nirkaufman@gmail.com
14. routing
The route object contain a ‘resolve’ property that
can accept a map of promises and wait for them to
resolve before performing the route
angular.module('moduleName', [])
.config(function($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'view.html',
controller : 'controller.js',
resolve : // promise
})
})
});
nirkaufman@gmail.com
15. routing
If every view managed by a controller we can
reflect that in our project structure by packing them
together & come up with naming conventions:
❖ views
➢ view-name
■ view-name.html
■ view-name.js
.controller(‘viewNameCtrl’, ….
➢ another-view
■ another-view-name.html
■ another-view-name.js
nirkaufman@gmail.com
16. events
We can load our dependencies as a reaction to an
event.
we can be creative and load our resources
depending on the user behaviour:
● load only when a user start to fill a form
● load by mouse position
● load when a response comming back from
the server
nirkaufman@gmail.com
17. modules
What about module loading?
ocLazyLoad is probably the best solution for lazy
loading angular modules (for now):
● Dependencies are automatically loaded
● Debugger like (no eval code)
● The ability to mix normal boot and load on demand
● Load via the service or the directive
● Use your own async loader (requireJS, script.js ...)
https://github.com/ocombe/ocLazyLoad
nirkaufman@gmail.com
18. summary
Lazy loading in Angular can be achived today with
minimum effort.
to keep our loading infrastructure flexible:
1. keep the loading logic in separated services
this will make our life easier when this feature will
be officially supported
2. use naming conventions
this way developers can integrate more easily
when moving between projects
nirkaufman@gmail.com