The Art of AngularJS in 2015 - Angular Summit 2015
-
Upload
matt-raible -
Category
Technology
-
view
33.201 -
download
1
Transcript of The Art of AngularJS in 2015 - Angular Summit 2015
![Page 2: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/2.jpg)
Blogger on raibledesigns.com
Founder of AppFuse
Father, Skier, Mountain Biker, Whitewater Rafter
Web Framework Connoisseur
Who is Matt Raible?
Bus Lover
![Page 3: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/3.jpg)
How to Become an ArtistPart 1 of 3: Learn the Basics on Your Own
Take some time and try various mediums of artRecognize your strengthsDo your research and learn the basicsGet the supplies you will needObserve the world around youMake time for your art every daySeek out the opinions of othersDevelop your own style http://www.wikihow.com/Become-an-Artist
![Page 4: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/4.jpg)
Jobs on Dice.comSeptember 2015
0
500
1,000
1,500
2,000
Back
bone
Angu
lar
Embe
r
Knoc
kout
Reac
t
![Page 5: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/5.jpg)
Job Growth
0
500
1000
1500
2000
February 2014 January 2015 September 2015
Ember.js AngularJS Backbone Knockout React
![Page 6: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/6.jpg)
LinkedIn SkillsSeptember 2015
0
50,000
100,000
150,000
200,000
Back
bone
Angu
lar
Knoc
kout
Embe
r
Reac
t
![Page 7: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/7.jpg)
LinkedIn SkillsSeptember 2015
0
15,000
30,000
45,000
60,000
Back
bone
Knoc
kout
Embe
r
Reac
t
![Page 8: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/8.jpg)
Skills Growth
0
50000
100000
150000
200000
February 2014 January 2015 September 2015
Ember.js AngularJS Backbone Knockout React
![Page 9: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/9.jpg)
Google Trends
![Page 10: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/10.jpg)
Indeed Job Trends
Absolute
Relative
![Page 11: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/11.jpg)
Stack Overflow
![Page 12: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/12.jpg)
http://stackoverflow.com/research/developer-survey-2015
![Page 13: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/13.jpg)
![Page 14: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/14.jpg)
Who wants to learn ?
![Page 15: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/15.jpg)
The History of AngularJSStarted by Miško Hevery in 2009
GWT = 3 developers, 6 months
AngularJS = 1 developer, 3 weeks
Learn more:
https://www.youtube.com/watch?v=X0VsStcCCM8
![Page 16: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/16.jpg)
The History of AngularJS
0
4500
9000
13500
18000
Lines of Code
17,000
1,000
AngularJS GWT
![Page 17: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/17.jpg)
![Page 18: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/18.jpg)
Hello World
<!doctype html> <html ng-app> <head> <title>Hello World</title> </head> <body> <div> <label>Name:</label> <input type="text" ng-model="name" placeholder="Enter a name here"> <hr> <h1>Hello {{name}}!</h1> </div> <script src="http://code.angularjs.org/1.4.6/angular.min.js"></script> </body> </html>
![Page 19: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/19.jpg)
Architecture Principles
Structure
Testability
Boilerplate
D.R.Y.
![Page 20: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/20.jpg)
Getting Started
Start with Angular Seed
git clone https://github.com/angular/angular-seed.git
![Page 21: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/21.jpg)
App Definition
var app = angular.module('myApp', []);
<!DOCTYPE html> <html ng-app="myApp">
![Page 22: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/22.jpg)
Model View Controller
![Page 23: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/23.jpg)
Data Bindingfriend.js
friend.html
$scope.friend = { name: "Fernand" };
{{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way
![Page 24: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/24.jpg)
Solving FOUCThis will work just fine — if it’s not on the first page:
Use ng-cloak or ng-bind attribute:
<p>{{friend.name}}</p>
<p ng-cloak>{{friend.name}}</p>
<p ng-bind="friend.name"></p>
![Page 25: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/25.jpg)
Directives
<div ng-repeat="entry in news.entries"> <span ng-bind="entry.title"></span> <button ng-click="delete($index)"> Delete </button> </div>
![Page 26: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/26.jpg)
Directives with valid HTML5<div data-ng-repeat="entry in news.entries"> <span data-ng-bind="entry.title"></span> <button data-ng-click="delete($index)"> Delete </button> </div>
<div data-ng:repeat="entry in news.entries"> <span data-ng:bind="entry.title"></span> <button data-ng:click="delete($index)"> Delete </button> </div>
![Page 27: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/27.jpg)
Custom Directives$scope.customer = { name: 'Franklin', address: '1830 Blake' };
<div ng-controller="MyController"> <my-customer></my-customer> </div>
.directive('myCustomer', function() { return { template: 'Name: {{customer.name}} \ Address: {{customer.address}}' }; });
![Page 28: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/28.jpg)
Built-In Directivesng-href
ng-src
ng-disabled
ng-checked
ng-readonly
ng-selected
ng-class
ng-style
![Page 29: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/29.jpg)
Servicesvar services = angular.module('myApp.services', ['ngResource']);
services.factory('LoginService', function($resource) { return $resource(':action', {}, { authenticate: { method: 'POST', params: {'action': 'authenticate'}, headers: {'Content-Type': 'application/x-www-form-urlencoded'} } } ); });
services.factory('NewsService', function($resource) { return $resource('news/:id', {id: '@id'}); });
![Page 30: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/30.jpg)
$http$http({method: 'GET', url: '/news'}). success(function(data, status, headers, config) { // this callback will be called asynchronously // when the response is available }). error(function(data, status, headers, config) { // called asynchronously if an error occurs // or server returns response with an error status. });
$http.get('/news').success(successCallback); $http.post('/news', data).success(successCallback);
![Page 31: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/31.jpg)
$qmyApp.factory('HelloWorld', function($q, $timeout) {
var getMessages = function() { var deferred = $q.defer();
$timeout(function() { deferred.resolve(['Hello', 'world!']); }, 2000);
return deferred.promise; };
return { getMessages: getMessages }; });
![Page 32: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/32.jpg)
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; });
});
![Page 33: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/33.jpg)
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location, $http, $cookieStore, LoginService) { $scope.login = function () { LoginService.authenticate($.param({username: $scope.username, password: $scope.password}),
function (user) { $rootScope.user = user; $http.defaults.headers.common[xAuthTokenHeaderName] = user.token; $cookieStore.put('user', user); $location.path("/"); });
}; })
![Page 34: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/34.jpg)
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location, $http, $cookieStore, LoginService) { $scope.login = function () { LoginService.authenticate($.param({username: $scope.username, password: $scope.password}),
function (user) { $rootScope.user = user; $http.defaults.headers.common[xAuthTokenHeaderName] = user.token; $cookieStore.put('user', user); $location.path("/"); });
}; })
![Page 35: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/35.jpg)
Filters
also: lowercase, limitTo, orderBy
{{ name | uppercase }}
<!-- Displays: 123.46 --> {{ 123.456789 | number:2 }}
<!-- In en-US locale, '$1000.00' will be shown --> {{ 1000 | currency }}
<!-- all of the words with e in them ["Lerner","Likes","Eat"] --> {{ ['Ari', 'Lerner', 'Likes', 'To', 'Eat', 'Pizza'] | filter:'e' }}
![Page 36: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/36.jpg)
Routes.config(['$routeProvider', '$locationProvider', '$httpProvider', function ($routeProvider, $locationProvider, $httpProvider) { $routeProvider.when('/create', { templateUrl: 'partials/create.html', controller: 'CreateController' }); $routeProvider.when('/edit/:id', { templateUrl: 'partials/edit.html', controller: 'EditController' }); $routeProvider.when('/login', { templateUrl: 'partials/login.html', controller: 'LoginController' }); $routeProvider.otherwise({ templateUrl: 'partials/index.html', controller: 'IndexController' });
$locationProvider.hashPrefix('!'); }] )
![Page 37: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/37.jpg)
Routing: Navigation
$rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
![Page 38: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/38.jpg)
Routing: Navigation
$rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
![Page 39: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/39.jpg)
UI-Routerangular.module('myApp.search', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) { $stateProvider .state('search', { url: '/search', templateUrl: 'search/index.html', controller: 'SearchController' }) .state('edit', { url: '/edit/:id', templateUrl: 'search/edit.html', controller: 'EditController' }) .state('search-auto', { url: '/search/:term', templateUrl: 'search/index.html', controller: 'SearchController' }) }])
![Page 40: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/40.jpg)
ngRouteangular.module('myApp.search', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) { $routeProvider .when('/search', { templateUrl: 'search/index.html', controller: 'SearchController' }) .when('/edit/:id', { templateUrl: 'search/edit.html', controller: 'EditController' }) .when('/search/:term', { templateUrl: 'search/index.html', controller: 'SearchController' }) }])
![Page 41: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/41.jpg)
![Page 42: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/42.jpg)
TestingKarma - test runner, framework agnostic
Jasmine - unit tests, framework agnostic
Protractor - integration tests, Angular-specific
Lineman - productivity, framework agnostic
![Page 43: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/43.jpg)
Testing: Controllersdescribe("controller: LoginController", function() {
beforeEach(function() { module("app"); });
beforeEach(inject(function($controller, $rootScope, $location, AuthenticationService, $httpBackend) { this.$location = $location; this.$httpBackend = $httpBackend; this.scope = $rootScope.$new(); this.redirect = spyOn($location, 'path'); $controller('LoginController', { $scope: this.scope, $location: $location, AuthenticationService: AuthenticationService }); }));
![Page 44: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/44.jpg)
Testing: Controllers afterEach(function() { this.$httpBackend.verifyNoOutstandingRequest(); this.$httpBackend.verifyNoOutstandingExpectation(); });
describe("successfully logging in", function() { it("should redirect you to /home", function() { this.$httpBackend.expectPOST('/login', this.scope.credentials).respond(200); this.scope.login(); this.$httpBackend.flush(); expect(this.redirect).toHaveBeenCalledWith('/home'); }); }); });
![Page 45: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/45.jpg)
Testing: DirectivesbeforeEach(inject(function($rootScope, $compile) { this.directiveMessage = 'ralph was here'; this.html = "<div shows-message-when-hovered message='" + this.directiveMessage + "'></div>"; this.scope = $rootScope.$new(); this.scope.message = this.originalMessage = 'things are looking grim'; this.elem = $compile(this.html)(this.scope); }));
describe("when a user mouses over the element", function() { it("sets the message on the scope to the message attribute", function() { this.elem.triggerHandler('mouseenter'); expect(this.scope.message).toBe(this.directiveMessage); }); });
![Page 46: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/46.jpg)
Testing: Directives with CoffeeScriptdescribe "directive: shows-message-when-hovered (coffeescript)", ->
Given -> module("app")
Given inject ($rootScope, $compile) -> @directiveMessage = 'ralph was here' @html = "<div shows-message-when-hovered message='#{@directiveMessage}'></div>" @scope = $rootScope.$new() @scope.message = @originalMessage = 'things are looking grim' @elem = $compile(@html)(@scope)
describe "when a user mouses over the element", -> When -> @elem.triggerHandler('mouseenter') Then "the message on the scope is set to the message attribute", -> @scope.message == @directiveMessage
![Page 47: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/47.jpg)
Testing: End-to-End
protractor = require("protractor") require "protractor/jasminewd" require 'jasmine-given'
describe "my angular app", -> ptor = protractor.getInstance() describe "visiting the login page", -> Given -> ptor.get "/"
describe "when a user logs in", -> Given -> ptor.findElement(protractor.By.input("credentials.username")).sendKeys "Ralph" Given -> ptor.findElement(protractor.By.input("credentials.password")).sendKeys "Wiggum" When -> ptor.findElement(protractor.By.id("log-in")).click() Then -> ptor.findElement(protractor.By.binding("{{ message }}")).getText().then (text) -> expect(text).toEqual "Mouse Over these images to see a directive at work"
![Page 48: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/48.jpg)
Testing: End-to-End
browser.get('/'); expect(element.all(by.css('.img-responsive')).first().getAttribute("alt")). toMatch(/StyleSelect/);
element(by.model('user.email')).sendKeys(email); element(by.model('user.password')).sendKeys(password); element(by.css('button[type=submit]')).click();
browser.driver.wait(protractor.until.elementIsVisible($('.app-content'))); var greeting = $('#greeting').getText(); var expectedGreeting = new RegExp('Welcome ' + firstName); expect(greeting).toMatch(expectedGreeting);
![Page 49: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/49.jpg)
Building with Grunt
sudo npm install
sudo npm install -g grunt-cli
vi package.json
"grunt": "0.4.5", "grunt-contrib-concat": "0.5.1", "grunt-contrib-uglify": "0.9.2", "grunt-contrib-cssmin": "0.14.0", "grunt-usemin": "3.1.1", "grunt-contrib-copy": "0.8.1", "grunt-rev": "~0.1.0", "grunt-contrib-clean": "~0.6.0", "matchdep": "~0.3.0"
![Page 50: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/50.jpg)
Gruntfile.jsmodule.exports = function (grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ pkg: grunt.file.readJSON('package.json'),
clean: ["dist", '.tmp'],
copy: { main: { expand: true, cwd: 'app/', src: ['**', '!js/**', '!lib/**', '!**/*.css'], dest: 'dist/' } },
rev: { files: { src: ['dist/**/*.{js,css}', '!dist/js/shims/**'] } },
![Page 51: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/51.jpg)
Gruntfile.js useminPrepare: { html: 'app/index.html' },
usemin: { html: ['dist/index.html'] },
uglify: { options: { report: 'min', mangle: false } } });
// Tell Grunt what to do when we type "grunt" into the terminal grunt.registerTask('default', [ 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin' ]); };
![Page 52: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/52.jpg)
index.html comments<head> <title>My AngularJS App</title> <!-- build:css css/seed.min.css --> <link rel="stylesheet" href="css/app.css"/> <link rel="stylesheet" href="css/app2.css"/> <!-- endbuild --> </head> <body> <!-- build:js js/seed.min.js --> <script src="lib/angular/angular.js"></script> <script src="lib/angular/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> <!-- endbuild --> </body>
![Page 53: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/53.jpg)
dist/index.html
<head> <title>My AngularJS App</title> <link rel="stylesheet" href="css/f050d0dc.seed.min.css"/> </head> <body>
<script src="js/8973cf0f.seed.min.js"></script> </body>
![Page 54: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/54.jpg)
After Grunt
http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
![Page 55: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/55.jpg)
You shouldn’t have to worry about FEO
http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
![Page 56: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/56.jpg)
HTTP/2 Performance Anti-Patterns?Split dominant content domains
Reduce requests
Merging
Sprites
DataURIshttp://www.slideshare.net/andydavies
![Page 57: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/57.jpg)
UI Bootstrap http://angular-ui.github.io/bootstrap
<script src="lib/angular/ui-bootstrap-0.13.4.min.js"></script> <script src="lib/angular/ui-bootstrap-tpls-0.13.4.min.js"></script>
angular.module('myApp', ['ui.bootstrap']);
![Page 58: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/58.jpg)
UI Bootstrap: Carousel
![Page 59: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/59.jpg)
UI Bootstrap: Carousel
<div ng-controller="CarouselDemoCtrl"> <div style="height: 305px"> <carousel interval="myInterval"> <slide ng-repeat="slide in slides" active="slide.active"> <img ng-src="{{slide.image}}" style="margin:auto;"> <div class="carousel-caption"> <h4>Slide {{$index}}</h4> <p>{{slide.text}}</p> </div> </slide> </carousel> </div> </div>
![Page 60: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/60.jpg)
Foundation for Apps http://foundation.zurb.com/apps
![Page 61: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/61.jpg)
Foundation
![Page 62: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/62.jpg)
Native AngularJS directives based on Foundation's markup and CSS
No dependency on jQuery or Foundation's JavaScript is required
Angular Foundation http://pineconellc.github.io/angular-foundation/
<script src="bower_components/angular-foundation/mm-foundation.min.js"></script> <script src="bower_components/angular_foundation/mm-foundation-tpls.min.js"></script>
angular.module('myApp', ['mm.foundation']);
![Page 64: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/64.jpg)
#dv13javaweb$
My Ionic Experience
http://raibledesigns.com/rd/entry/developing_an_ios_native_app
![Page 66: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/66.jpg)
JHipster
Spring Boot
Spring Security
AngularJS
Bootstrap
Bower
Metrics
Java 7 or Java 8
Maven or Gradle
Authentication Type: cookie-based or OAuth2
Type of Database: SQL or NoSQL
Caching: EhCache or Hazelcast
Grunt or Gulp.js
http://jhipster.github.io/
Foundational Frameworks Project Options
![Page 67: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/67.jpg)
JHipster
![Page 68: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/68.jpg)
JHipster: Metrics
![Page 69: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/69.jpg)
JHipster: Code Generation
![Page 70: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/70.jpg)
JHipster: Code Generation
![Page 71: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/71.jpg)
AngularJS Batarang
![Page 72: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/72.jpg)
Angular 2.0
<input type="text" [value]="firstName">
<button (click)="addPerson()">Add</button>
<input type="checkbox" [checked]="someProperty">
![Page 73: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/73.jpg)
Concepts Eliminated in 2.0Controllers
Directive Definition Object
$scope
angular.module
jqLite
![Page 74: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/74.jpg)
The Bad NewsNo migration path from Angular 1.x to 2.0
Angular 1.3 will be supported for 1.5 - 2 years
Will only support Evergreen Browsers (e.g. IE10+)
Learn more on
http://www.infoq.com/news/2014/10/angular-2-atscript
![Page 75: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/75.jpg)
![Page 76: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/76.jpg)
Good News!Angular 1 and Angular 2 can be mixed in the same application
You can mix Angular 1 and Angular 2 components in the same view
Angular 1 and Angular 2 can inject services across frameworks
Data binding works across frameworks
http://angularjs.blogspot.com/2015/08/angular-1-and-angular-2-coexistence.html
![Page 77: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/77.jpg)
Angular 1 to 2 Example
![Page 78: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/78.jpg)
How to Become an ArtistPart 1 of 3: Learn the Basics on Your Own
Take some time and try various mediums of artRecognize your strengthsDo your research and learn the basicsGet the supplies you will needObserve the world around youMake time for your art every daySeek out the opinions of othersDevelop your own style http://www.wikihow.com/Become-an-Artist
![Page 79: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/79.jpg)
Shortcut to becoming an Angular Artist
JUST DO IT.
![Page 80: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/80.jpg)
Contact Me!http://raibledesigns.com
@mraible
Presentationshttp://slideshare.net/mraible
Codehttp://github.com/mraible
Questions?
![Page 81: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/81.jpg)
Who to follow on Twitter
AngularJS Team at Google
Miško Hevery - @mhevery
Igor Minar - @IgorMinar
Brian Ford - @briantford
Web Performance
Ilya Grigorik - @igrigorik
Andy Davis - @andydavies
Steve Souders - @Souders
![Page 82: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/82.jpg)
My Experience in 2013Developing with AngularJS Series
Part I: The BasicsPart II: Dialogs and Data Part III: ServicesPart IV: Making it Pop
![Page 83: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/83.jpg)
#dv13javaweb$
My Experience in 2013
http://vimeo.com/mraible/angularjs-deep-dive
![Page 84: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/84.jpg)
2015 AngularJS TutorialsGetting Started with AngularJS
http://raibledesigns.com/rd/entry/getting_started_with_angularjs
Testing AngularJS Applications
http://raibledesigns.com/rd/entry/testing_angularjs_applications
![Page 85: The Art of AngularJS in 2015 - Angular Summit 2015](https://reader033.fdocuments.in/reader033/viewer/2022051709/5872b30e1a28ab523c8b5ec7/html5/thumbnails/85.jpg)
Spring and AngularJS http://spring.io/blog
http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application