Integrating Angular js & three.js
Josh Staples 
@cubicleDowns 
blog.tempt3d.com 
github.com/cubicleDowns/ng-three-viewer
WHO? Software Engineer @ napofearth.com 
“Explore Music Visually” PRIVATE BETA (#ngmeetup)
TODAY 
1. (v1) Angular & Three.js 3D Model Viewer 
2. (v2) “Controller as” & 
prototypal Angular components 
3. Grunt & Closure compilation approaches 
4. (v3*) Scoped scene graph
WHY? 
Great pattern(s) with low barrier of entry 
& high productivity 
All web devs can easily be 3D web devs 
Isolate THREE code from Angular UI/UX code!
THREE WHAT? 
threejs.org three features 
● Renderers 
● Scene Graph 
● Cameras 
● Animation 
● Lights 
● Materials 
● Shaders 
● Objects 
● Geometry 
● Loaders 
● Utilities 
● Export/Import 
● Support 
● Examples 
● WebVR 
● DIYVR 
Started by Mr. Doob on April 23, 2010
ANGULAR WHO?
Demo v1 
http://localhost:8000/v1/dist/
CONTROLLER 
AppController 
CONTROLLER 
FileLoaderController 
UI Elements and Controllers 
DIRECTIVE INCLUDE 
file-loader.html 
DIRECTIVE INCLUDE 
about.html 
DIRECTIVE INCLUDE 
chrome.html 
DIRECTIVE INCLUDE 
toolbar.html
CONTROLLER 
FileLoaderController 
Dependency Injections Across Angular Components 
CONTROLLER 
AppController 
DIRECTIVE 
select 
SERVICE 
StorageService 
SERVICE 
MessageBus 
FACTORY 
Viewer
Viewer.factory('ViewerFactory', … ) { 
init() 
home = new Viewer.Scene() 
animate () 
render () 
makeSelection () 
loadOBJMTL () 
loadGLTF () 
loadOBJ () 
loadJSON () 
scale () 
rotate () 
/** Translate the model along an axis 
* @param {number} x 
* @param {number} y 
* @param {number} z */ 
translate (x,y,z) 
home.wrangler.currentModel.position.set(x, y, z); 
CONTROLLER 
AppController 
● init () 
● rotate () 
● scale () 
● translate () 
SERVICE 
MessageBus 
DIRECTIVE 
select 
● makeSelection () 
CONTROLLER 
FileLoaderController 
● loadOBJMTL () 
● loadGLTF () 
● loadOBJ () 
● loadJSON () 
Viewer Factory Interface
Viewer Factory Architecture 
Viewer Factory Singleton 
function init(params) { 
home = new Viewer.Scene(params); 
animate(); 
} 
Viewer.Scene() 
this.scene 
THREE.Scene() 
this.renderer 
THREE.WebGLRenderer() 
this.wrangler 
Viewer.Wrangler() 
function animate () { 
requestAnimationFrame(animate); 
render(); 
} 
this.setup 
Viewer.Setup() 
this.cameras 
Viewer.Cameras() 
this.controls 
THREE.OrbitControls() 
this.raycaster 
THREE.Raycaster()
USE CASE - User Click, Intersect 3D Model, Return Model Information 
Angular Directive, <canvas select> 
elem.on(tap, function(e) 
x = e.gesture.center.x; 
y = e.gesture.center.y; 
// creating NDC coordinates for ray intersection. 
mouseDown.x = (x / width) * 2 - 1; 
mouseDown.y = -(y / height) * 2 + 1; 
ViewerFactory.makeSelection(mouseDown); 
Viewer Factory, makeSelection 
makeSelection(mouse): 
Angular Controller/Factory 
$scope.$on(‘objectSelected’, function () { 
// Do Something. 
}); 
var vector = new THREE.Vector3( mouse.x, mouse.y, 1).unproject(home.cameras.liveCam); 
home.raycaster.set(home.cameras.liveCam.position, vector.sub(home.cameras.liveCam.position).normalize()); 
var intersected = home.raycaster.intersectObjects(home.wrangler.currentModel, true); 
MessageBus.trigger('objectSelected', intersected[0])
MOST PROFITABLE MOVIE?
MOST PROFITABLE MOVIE? 
THE SEQUEL!
STARRING 
“Controller as” 
& 
as ctrl 
Annotations 
as SNAFU
Sequel (v2) 
http://localhost:8000/v2/dist/
Controller as 
<div id="file-loader" ng-controller="FileLoaderController as loader" ng-show=”loader.visible”> 
<input type="text" ng-model="loader.data.obj" placeholder="obj file url"> 
<input type="text" ng-model="loader.data.name" placeholder="unique name"> 
<button ng-click="otherLoader.loadOBJMTL()">Load OBJ/MTL</button> 
<button ng-click="loader.loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> 
Controller 
level scope 
:) 
<div id="file-loader" ng-controller="FileLoaderController" ng-show=”visible”> 
- - - 
<input type="text" ng-model="data.obj" placeholder="obj file url"> 
<input type="text" ng-model="data.mtl" placeholder="mtl file url"> 
<button ng-click="loadOBJMTL()">Load OBJ/MTL</button> 
<button ng-click="loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> 
nearest scope 
:(
Service, !Factory 
Viewer.ViewerService 
.prototype 
init 
listeners 
animate 
render 
makeSelection 
loadOBJMTL 
loadOBJ 
loadGLTF 
loadJSON 
rotate 
translate 
scale 
● No More Factories 
○ closure pattern 
● Instead, prototypal Service 
○ ‘new’ and this 
○ .bind() for callbacks 
● Saves Memory, Time, Searches (sorry) 
● Single Pattern For Everything! 
● IMHO, the best way to code JS
/** @ngInject */ 
Viewer.ViewerService = function($timeout, MessageBus){ 
this.timeout = $timeout; 
this.MessageBus = MessageBus; 
}; 
Viewer.ViewerService.prototype.init = function (params){ 
this.home = new Viewer.Scene(params); 
this.MessageBus.trigger(‘app-ready’); 
animate(); 
}; 
Viewer.factory('ViewerFactory', ['MessageBus', function (MessageBus) 
function init () {} 
function makeSelection() {} 
return { 
init: init, 
makeSelection: makeSelection 
} 
closure style, 
ng-annotate 
: 
prototypal 
:) 
Prototypal Angular
CAonnntorotallteior nass 
/** Service which initiates the THREE.js scene and 
* provides methods to interact with that scene 
* 
* @param {angular.$timeout} $timeout 
* @param {!Viewer.MessageBus} MessageBus 
* @constructor 
* @ngInject 
*/ 
Viewer.ViewerService = function($timeout, MessageBus){ 
this.timeout = $timeout; 
this.MessageBus = MessageBus; 
}; 
/** 
* Translate the model along an axis 
* @param {number} x 
* @param {number} y 
* @param {number} z 
*/ 
Viewer.ViewerService.prototype.translate = function(x, y, z){ 
this.home.wrangler.currentModel.position.set(x, y, z) 
}; 
/** 
* @param {number} s 
*/ 
Viewer.ViewerService.prototype.scale = function(s) { 
this.home.wrangler.currentModel.scale.set(s, s, s); 
}; 
The Closure Compiler can use data type 
information about JavaScript variables to provide 
enhanced optimization and warnings.
APP INIT (app.js) 
angular.module('ThreeViewer', ['ngHammer', 'ngRoute', 'LocalStorageModule']) 
.config(['localStorageServiceProvider',function(localStorageServiceProvider){ 
…. 
.config(['$locationProvider', function($locationProvider) { 
…. 
$locationProvider.html5Mode(true); 
.config(['$routeProvider', function($routeProvider){ 
angular.module('ThreeViewer', ['ngRoute', 'LocalStorageModule']) 
.config(ThreeViewer.ConfigLocation) 
…. 
.directive('select', ['ViewerService', ThreeViewer.SelectDirective.factory]) 
…. 
.filter('forceInt', ThreeViewer.ForceInt.factory) 
…. 
.service('ViewerService', [MessageBus', ThreeViewer.ViewerService]) 
…. 
.controller('AppController', ['$scope', 'ViewerService', ThreeViewer.AppController]); 
v2 
:) 
v1 
:
uglify: { 
ng3: { 
options: { 
compress: { 
drop_console: true 
}, 
sourceMap: true, 
}, 
files: { 
'dist/app.min.js': ['<%= concat.ng3.dest %>'] 
} 
} 
}, 
command: 'java -jar closure/compiler.jar ' + 
'--compilation_level SIMPLE_OPTIMIZATIONS' + 
'--language_in ECMASCRIPT5_STRICT ' + 
'--angular_pass ' + 
'--externs closure/externs/angular-1.3.js ' + 
'--externs closure/externs/three.js ' + 
'--generate_exports ' + 
'--manage_closure_dependencies ' + 
'--js closure/library/base.js ' + 
'--js <%= app %> ' + 
'--js <%= ng %> ' + 
'--js <%= three %> ' + 
'--js_output_file dist/app.min.js' 
Minify or Closure Compilation? 
Closure Compiler 
● type checking 
● ngInject 
● goog.provide / require 
Grunt ng-annotate 
● uglify 
● ng-annotate
NOGN Eto A TPHPR, ETEWO PATTERNS 
V1 
● Most Common Angular Pattern 
● Grunt uglify / minify 
● Factories 
● Services 
● Filters 
● Directives 
● Init controllers from DOM 
V2 
● Prototypal Pattern for Everything! 
● Bridge to Angular 2.0 
● Controller as (local scope) 
● Closure Compilation 
○ type checking 
○ -- angular_pass 
○ dependency chains 
○ minification 
● App.js Initialization 
● No closure pattern (factories)
JNOGIN t oU TSH! REE Mobile Developer - Backend Guru 
napofearth.com/jobs UI/UX Designer - QA #ngmeetup

More Related Content

PPTX
Developing Web Graphics with WebGL
PPTX
AngularJs
PDF
AngularJS Framework
PDF
Building scalable applications with angular js
PDF
Advanced Tips & Tricks for using Angular JS
PPTX
Angularjs Basics
ODP
AngularJs Crash Course
PDF
Building a Startup Stack with AngularJS
Developing Web Graphics with WebGL
AngularJs
AngularJS Framework
Building scalable applications with angular js
Advanced Tips & Tricks for using Angular JS
Angularjs Basics
AngularJs Crash Course
Building a Startup Stack with AngularJS

What's hot (20)

PDF
Workshop 12: AngularJS Parte I
PDF
AngularJS Basics with Example
PPTX
AngularJS Internal
PDF
준비하세요 Angular js 2.0
PPTX
AngularJS Architecture
PPTX
Practical AngularJS
KEY
CocoaHeads Toulouse - Guillaume Cerquant - UIView
PDF
What's new in iOS9
PPTX
Angular js
PPTX
Angularjs Performance
KEY
AngularJS for designers and developers
PPTX
AngularJS with TypeScript and Windows Azure Mobile Services
PDF
AngularJS Basic Training
PPTX
AngularJS $Provide Service
PPTX
AngularJS Animations
PPTX
The AngularJS way
PDF
Angular js routing options
PDF
Workshop 9: BackboneJS y patrones MVC
PDF
MVC-RS par Grégoire Lhotelier
PPTX
Intro to AngularJs
Workshop 12: AngularJS Parte I
AngularJS Basics with Example
AngularJS Internal
준비하세요 Angular js 2.0
AngularJS Architecture
Practical AngularJS
CocoaHeads Toulouse - Guillaume Cerquant - UIView
What's new in iOS9
Angular js
Angularjs Performance
AngularJS for designers and developers
AngularJS with TypeScript and Windows Azure Mobile Services
AngularJS Basic Training
AngularJS $Provide Service
AngularJS Animations
The AngularJS way
Angular js routing options
Workshop 9: BackboneJS y patrones MVC
MVC-RS par Grégoire Lhotelier
Intro to AngularJs
Ad

Viewers also liked (20)

PDF
Angular 2のRenderer
PDF
About WinJS
PDF
PDF
A-Frame: VR for Web Developers
PPTX
WebGL and three.js - Web 3D Graphics
PDF
Build the Virtual Reality Web with A-Frame
PDF
Introduction to WebGL and WebVR
PDF
The next frontier: WebGL and WebVR
PPTX
PDF
WebVR - MobileTechCon Berlin 2016
PDF
An Introduction to WebVR – or How to make your user sick in 60 seconds
PDF
Bringing Virtual Reality to the Web: VR, WebGL and CSS – Together At Last!
PDF
Virtually Anyone
PDF
Foundations of the Immersive Web
PPTX
WebGL, HTML5 and How the Mobile Web Was Won
PPTX
Hacking Reality: Browser-Based VR with HTML5
PPTX
Powering the VR/AR Ecosystem 2017-01-17
PPTX
WebGL: The Next Generation
PPTX
An Introduction to Web VR January 2015
PDF
The Immersive Web
Angular 2のRenderer
About WinJS
A-Frame: VR for Web Developers
WebGL and three.js - Web 3D Graphics
Build the Virtual Reality Web with A-Frame
Introduction to WebGL and WebVR
The next frontier: WebGL and WebVR
WebVR - MobileTechCon Berlin 2016
An Introduction to WebVR – or How to make your user sick in 60 seconds
Bringing Virtual Reality to the Web: VR, WebGL and CSS – Together At Last!
Virtually Anyone
Foundations of the Immersive Web
WebGL, HTML5 and How the Mobile Web Was Won
Hacking Reality: Browser-Based VR with HTML5
Powering the VR/AR Ecosystem 2017-01-17
WebGL: The Next Generation
An Introduction to Web VR January 2015
The Immersive Web
Ad

Similar to Integrating Angular js & three.js (8)

PDF
Three.js basics
PDF
From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014
ODP
Introduction to threejs
PDF
Begin three.js.key
PDF
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
PDF
WebGL 3D player
PDF
3D everywhere
PDF
Augmented reality in web rtc browser
Three.js basics
From Hello World to the Interactive Web with Three.js: Workshop at FutureJS 2014
Introduction to threejs
Begin three.js.key
3D Web Programming [Thanh Loc Vo , CTO Epsilon Mobile ]
WebGL 3D player
3D everywhere
Augmented reality in web rtc browser

Recently uploaded (20)

PPTX
Computer Software - Technology and Livelihood Education
PDF
iTop VPN Crack Latest Version Full Key 2025
PDF
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
PDF
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
PDF
Visual explanation of Dijkstra's Algorithm using Python
PPTX
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
PDF
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
PDF
DNT Brochure 2025 – ISV Solutions @ D365
PDF
AI Guide for Business Growth - Arna Softech
PDF
Type Class Derivation in Scala 3 - Jose Luis Pintado Barbero
PDF
Workplace Software and Skills - OpenStax
PPTX
Matchmaking for JVMs: How to Pick the Perfect GC Partner
PPTX
GSA Content Generator Crack (2025 Latest)
DOC
UTEP毕业证学历认证,宾夕法尼亚克拉里恩大学毕业证未毕业
PPTX
Trending Python Topics for Data Visualization in 2025
PDF
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
PDF
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
DOCX
How to Use SharePoint as an ISO-Compliant Document Management System
PDF
Guide to Food Delivery App Development.pdf
PPTX
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx
Computer Software - Technology and Livelihood Education
iTop VPN Crack Latest Version Full Key 2025
DuckDuckGo Private Browser Premium APK for Android Crack Latest 2025
EaseUS PDF Editor Pro 6.2.0.2 Crack with License Key 2025
Visual explanation of Dijkstra's Algorithm using Python
MLforCyber_MLDataSetsandFeatures_Presentation.pptx
Top 10 Software Development Trends to Watch in 2025 🚀.pdf
DNT Brochure 2025 – ISV Solutions @ D365
AI Guide for Business Growth - Arna Softech
Type Class Derivation in Scala 3 - Jose Luis Pintado Barbero
Workplace Software and Skills - OpenStax
Matchmaking for JVMs: How to Pick the Perfect GC Partner
GSA Content Generator Crack (2025 Latest)
UTEP毕业证学历认证,宾夕法尼亚克拉里恩大学毕业证未毕业
Trending Python Topics for Data Visualization in 2025
AI/ML Infra Meetup | Beyond S3's Basics: Architecting for AI-Native Data Access
AI-Powered Threat Modeling: The Future of Cybersecurity by Arun Kumar Elengov...
How to Use SharePoint as an ISO-Compliant Document Management System
Guide to Food Delivery App Development.pdf
Cybersecurity-and-Fraud-Protecting-Your-Digital-Life.pptx

Integrating Angular js & three.js

  • 2. Josh Staples @cubicleDowns blog.tempt3d.com github.com/cubicleDowns/ng-three-viewer
  • 3. WHO? Software Engineer @ napofearth.com “Explore Music Visually” PRIVATE BETA (#ngmeetup)
  • 4. TODAY 1. (v1) Angular & Three.js 3D Model Viewer 2. (v2) “Controller as” & prototypal Angular components 3. Grunt & Closure compilation approaches 4. (v3*) Scoped scene graph
  • 5. WHY? Great pattern(s) with low barrier of entry & high productivity All web devs can easily be 3D web devs Isolate THREE code from Angular UI/UX code!
  • 6. THREE WHAT? threejs.org three features ● Renderers ● Scene Graph ● Cameras ● Animation ● Lights ● Materials ● Shaders ● Objects ● Geometry ● Loaders ● Utilities ● Export/Import ● Support ● Examples ● WebVR ● DIYVR Started by Mr. Doob on April 23, 2010
  • 9. CONTROLLER AppController CONTROLLER FileLoaderController UI Elements and Controllers DIRECTIVE INCLUDE file-loader.html DIRECTIVE INCLUDE about.html DIRECTIVE INCLUDE chrome.html DIRECTIVE INCLUDE toolbar.html
  • 10. CONTROLLER FileLoaderController Dependency Injections Across Angular Components CONTROLLER AppController DIRECTIVE select SERVICE StorageService SERVICE MessageBus FACTORY Viewer
  • 11. Viewer.factory('ViewerFactory', … ) { init() home = new Viewer.Scene() animate () render () makeSelection () loadOBJMTL () loadGLTF () loadOBJ () loadJSON () scale () rotate () /** Translate the model along an axis * @param {number} x * @param {number} y * @param {number} z */ translate (x,y,z) home.wrangler.currentModel.position.set(x, y, z); CONTROLLER AppController ● init () ● rotate () ● scale () ● translate () SERVICE MessageBus DIRECTIVE select ● makeSelection () CONTROLLER FileLoaderController ● loadOBJMTL () ● loadGLTF () ● loadOBJ () ● loadJSON () Viewer Factory Interface
  • 12. Viewer Factory Architecture Viewer Factory Singleton function init(params) { home = new Viewer.Scene(params); animate(); } Viewer.Scene() this.scene THREE.Scene() this.renderer THREE.WebGLRenderer() this.wrangler Viewer.Wrangler() function animate () { requestAnimationFrame(animate); render(); } this.setup Viewer.Setup() this.cameras Viewer.Cameras() this.controls THREE.OrbitControls() this.raycaster THREE.Raycaster()
  • 13. USE CASE - User Click, Intersect 3D Model, Return Model Information Angular Directive, <canvas select> elem.on(tap, function(e) x = e.gesture.center.x; y = e.gesture.center.y; // creating NDC coordinates for ray intersection. mouseDown.x = (x / width) * 2 - 1; mouseDown.y = -(y / height) * 2 + 1; ViewerFactory.makeSelection(mouseDown); Viewer Factory, makeSelection makeSelection(mouse): Angular Controller/Factory $scope.$on(‘objectSelected’, function () { // Do Something. }); var vector = new THREE.Vector3( mouse.x, mouse.y, 1).unproject(home.cameras.liveCam); home.raycaster.set(home.cameras.liveCam.position, vector.sub(home.cameras.liveCam.position).normalize()); var intersected = home.raycaster.intersectObjects(home.wrangler.currentModel, true); MessageBus.trigger('objectSelected', intersected[0])
  • 15. MOST PROFITABLE MOVIE? THE SEQUEL!
  • 16. STARRING “Controller as” & as ctrl Annotations as SNAFU
  • 18. Controller as <div id="file-loader" ng-controller="FileLoaderController as loader" ng-show=”loader.visible”> <input type="text" ng-model="loader.data.obj" placeholder="obj file url"> <input type="text" ng-model="loader.data.name" placeholder="unique name"> <button ng-click="otherLoader.loadOBJMTL()">Load OBJ/MTL</button> <button ng-click="loader.loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> Controller level scope :) <div id="file-loader" ng-controller="FileLoaderController" ng-show=”visible”> - - - <input type="text" ng-model="data.obj" placeholder="obj file url"> <input type="text" ng-model="data.mtl" placeholder="mtl file url"> <button ng-click="loadOBJMTL()">Load OBJ/MTL</button> <button ng-click="loadSampleOBJMTL()">SAMPLE OBJ-MTL</button> nearest scope :(
  • 19. Service, !Factory Viewer.ViewerService .prototype init listeners animate render makeSelection loadOBJMTL loadOBJ loadGLTF loadJSON rotate translate scale ● No More Factories ○ closure pattern ● Instead, prototypal Service ○ ‘new’ and this ○ .bind() for callbacks ● Saves Memory, Time, Searches (sorry) ● Single Pattern For Everything! ● IMHO, the best way to code JS
  • 20. /** @ngInject */ Viewer.ViewerService = function($timeout, MessageBus){ this.timeout = $timeout; this.MessageBus = MessageBus; }; Viewer.ViewerService.prototype.init = function (params){ this.home = new Viewer.Scene(params); this.MessageBus.trigger(‘app-ready’); animate(); }; Viewer.factory('ViewerFactory', ['MessageBus', function (MessageBus) function init () {} function makeSelection() {} return { init: init, makeSelection: makeSelection } closure style, ng-annotate : prototypal :) Prototypal Angular
  • 21. CAonnntorotallteior nass /** Service which initiates the THREE.js scene and * provides methods to interact with that scene * * @param {angular.$timeout} $timeout * @param {!Viewer.MessageBus} MessageBus * @constructor * @ngInject */ Viewer.ViewerService = function($timeout, MessageBus){ this.timeout = $timeout; this.MessageBus = MessageBus; }; /** * Translate the model along an axis * @param {number} x * @param {number} y * @param {number} z */ Viewer.ViewerService.prototype.translate = function(x, y, z){ this.home.wrangler.currentModel.position.set(x, y, z) }; /** * @param {number} s */ Viewer.ViewerService.prototype.scale = function(s) { this.home.wrangler.currentModel.scale.set(s, s, s); }; The Closure Compiler can use data type information about JavaScript variables to provide enhanced optimization and warnings.
  • 22. APP INIT (app.js) angular.module('ThreeViewer', ['ngHammer', 'ngRoute', 'LocalStorageModule']) .config(['localStorageServiceProvider',function(localStorageServiceProvider){ …. .config(['$locationProvider', function($locationProvider) { …. $locationProvider.html5Mode(true); .config(['$routeProvider', function($routeProvider){ angular.module('ThreeViewer', ['ngRoute', 'LocalStorageModule']) .config(ThreeViewer.ConfigLocation) …. .directive('select', ['ViewerService', ThreeViewer.SelectDirective.factory]) …. .filter('forceInt', ThreeViewer.ForceInt.factory) …. .service('ViewerService', [MessageBus', ThreeViewer.ViewerService]) …. .controller('AppController', ['$scope', 'ViewerService', ThreeViewer.AppController]); v2 :) v1 :
  • 23. uglify: { ng3: { options: { compress: { drop_console: true }, sourceMap: true, }, files: { 'dist/app.min.js': ['<%= concat.ng3.dest %>'] } } }, command: 'java -jar closure/compiler.jar ' + '--compilation_level SIMPLE_OPTIMIZATIONS' + '--language_in ECMASCRIPT5_STRICT ' + '--angular_pass ' + '--externs closure/externs/angular-1.3.js ' + '--externs closure/externs/three.js ' + '--generate_exports ' + '--manage_closure_dependencies ' + '--js closure/library/base.js ' + '--js <%= app %> ' + '--js <%= ng %> ' + '--js <%= three %> ' + '--js_output_file dist/app.min.js' Minify or Closure Compilation? Closure Compiler ● type checking ● ngInject ● goog.provide / require Grunt ng-annotate ● uglify ● ng-annotate
  • 24. NOGN Eto A TPHPR, ETEWO PATTERNS V1 ● Most Common Angular Pattern ● Grunt uglify / minify ● Factories ● Services ● Filters ● Directives ● Init controllers from DOM V2 ● Prototypal Pattern for Everything! ● Bridge to Angular 2.0 ● Controller as (local scope) ● Closure Compilation ○ type checking ○ -- angular_pass ○ dependency chains ○ minification ● App.js Initialization ● No closure pattern (factories)
  • 25. JNOGIN t oU TSH! REE Mobile Developer - Backend Guru napofearth.com/jobs UI/UX Designer - QA #ngmeetup