Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Photos by

The Art of in 2015
Matt Raible • http://raibledesigns.com
Blogger on raibledesigns.com
Founder of AppFuse
Father, Skier, Mountain
Biker, Whitewater Rafter
Web Framework Connoisseur...
How to Become an Artist
Part 1 of 3: Learn the Basics on Your Own

Take some time and try various mediums of art

Recogniz...
Jobs on Dice.com
September 2015
0
500
1,000
1,500
2,000
Backbone
Angular
Em
ber
Knockout
React
Job Growth
0
500
1000
1500
2000
February 2014 January 2015 September 2015
Ember.js AngularJS Backbone Knockout React
LinkedIn Skills
September 2015
0
50,000
100,000
150,000
200,000
Backbone
Angular
Knockout
Em
ber
React
LinkedIn Skills
September 2015
0
15,000
30,000
45,000
60,000
Backbone
Knockout
Em
ber
React
Skills Growth
0
50000
100000
150000
200000
February 2014 January 2015 September 2015
Ember.js AngularJS Backbone Knockout ...
Google Trends
Indeed Job Trends
Absolute
Relative
Stack Overflow
http://stackoverflow.com/research/developer-survey-2015
Who wants to learn ?
The History of AngularJS
Started by Miško Hevery in 2009

GWT = 3 developers, 6 months

AngularJS = 1 developer, 3 weeks

...
The History of AngularJS
0
4500
9000
13500
18000
Lines of Code
17,000
1,000
AngularJS GWT
Hello World
<!doctype html>
<html ng-app>
<head>
<title>Hello World</title>
</head>
<body>
<div>
<label>Name:</label>
<inp...
Architecture Principles
Structure
Testability
Boilerplate
D.R.Y.
Getting Started
Start with Angular Seed

git clone https://github.com/angular/angular-seed.git
App Definition
var app = angular.module('myApp', []);
<!DOCTYPE html>
<html ng-app="myApp">
Model View Controller
Data Binding
friend.js

friend.html

$scope.friend = {
name: "Fernand"
};
{{friend.name}} // 1-way
<input ng-model="friend...
Solving FOUC
This will work just fine — if it’s not on the first page:

Use ng-cloak or ng-bind attribute:

<p>{{friend.name...
Directives
<div ng-repeat="entry in news.entries">
<span ng-bind="entry.title"></span>
<button ng-click="delete($index)">
...
Directives with valid HTML5
<div data-ng-repeat="entry in news.entries">
<span data-ng-bind="entry.title"></span>
<button ...
Custom Directives
$scope.customer = {
name: 'Franklin',
address: '1830 Blake'
};
<div ng-controller="MyController">
<my-cu...
Built-In Directives
ng-href

ng-src

ng-disabled

ng-checked

ng-readonly

ng-selected

ng-class

ng-style
Services
var services = angular.module('myApp.services', ['ngResource']);
services.factory('LoginService', function($resou...
$http
$http({method: 'GET', url: '/news'}).
success(function(data, status, headers, config) {
// this callback will be cal...
$q
myApp.factory('HelloWorld', function($q, $timeout) {
var getMessages = function() {
var deferred = $q.defer();
$timeout...
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(function(messages) {
$scope....
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location,
$http, $cookieStore, LoginServ...
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location,
$http, $cookieStore, LoginServ...
Filters
also: lowercase, limitTo, orderBy
{{ name | uppercase }}
<!-- Displays: 123.46 -->
{{ 123.456789 | number:2 }}
<!-...
Routes
.config(['$routeProvider', '$locationProvider', '$httpProvider',
function ($routeProvider, $locationProvider, $http...
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTo...
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTo...
UI-Router
angular.module('myApp.search', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvi...
ngRoute
angular.module('myApp.search', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
...
Testing
Karma - test runner, framework agnostic

Jasmine - unit tests, framework agnostic

Protractor - integration tests,...
Testing: Controllers
describe("controller: LoginController", function() {
beforeEach(function() {
module("app");
});
befor...
Testing: Controllers
afterEach(function() {
this.$httpBackend.verifyNoOutstandingRequest();
this.$httpBackend.verifyNoOuts...
Testing: Directives
beforeEach(inject(function($rootScope, $compile) {
this.directiveMessage = 'ralph was here';
this.html...
Testing: Directives with CoffeeScript
describe "directive: shows-message-when-hovered (coffeescript)", ->
Given -> module(...
Testing: End-to-End
protractor = require("protractor")
require "protractor/jasminewd"
require 'jasmine-given'
describe "my...
Testing: End-to-End
browser.get('/');
expect(element.all(by.css('.img-responsive')).first().getAttribute("alt")).
toMatch(...
Building with Grunt
sudo npm install
sudo npm install -g grunt-cli
vi package.json
"grunt": "0.4.5",
"grunt-contrib-concat...
Gruntfile.js
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
pkg: grunt.file.rea...
Gruntfile.js
useminPrepare: {
html: 'app/index.html'
},
usemin: {
html: ['dist/index.html']
},
uglify: {
options: {
report:...
index.html comments
<head>
<title>My AngularJS App</title>
<!-- build:css css/seed.min.css -->
<link rel="stylesheet" href...
dist/index.html
<head>
<title>My AngularJS App</title>
<link rel="stylesheet" href="css/f050d0dc.seed.min.css"/>
</head>
<...
After Grunt
http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
You shouldn’t have to worry about FEO
http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
HTTP/2 Performance Anti-Patterns?
Split dominant content domains

Reduce requests

	 Merging

	 Sprites

	 DataURIs
http:/...
UI Bootstrap http://angular-ui.github.io/bootstrap
<script src="lib/angular/ui-bootstrap-0.13.4.min.js"></script>
<script ...
UI Bootstrap: Carousel
UI Bootstrap: Carousel
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel interval="myInterval">...
Foundation for Apps http://foundation.zurb.com/apps
Foundation
Native AngularJS directives based on
Foundation's markup and CSS

No dependency on jQuery or
Foundation's JavaScript is re...
Ionic Framework http://ionicframework.com
#dv13javaweb$
My Ionic Experience
http://raibledesigns.com/rd/entry/developing_an_ios_native_app
JHipster http://jhipster.github.io/
JHipster
Spring Boot

Spring Security

AngularJS

Bootstrap

Bower

Metrics

Java 7 or Java 8

Maven or Gradle

Authentica...
JHipster
JHipster: Metrics
JHipster: Code Generation
JHipster: Code Generation
AngularJS Batarang
Angular 2.0
<input type="text" [value]="firstName">
<button (click)="addPerson()">Add</button>
<input type="checkbox" [che...
Concepts Eliminated in 2.0
Controllers

Directive Definition Object

$scope

angular.module

jqLite
The Bad News
No migration path from Angular 1.x to 2.0

Angular 1.3 will be supported for 1.5 - 2 years

Will only support...
Good News!
Angular 1 and Angular 2 can be mixed in the same application

You can mix Angular 1 and Angular 2 components in...
Angular 1 to 2 Example
How to Become an Artist
Part 1 of 3: Learn the Basics on Your Own

Take some time and try various mediums of art

Recogniz...
Shortcut to becoming an Angular Artist
JUST DO IT.
Contact Me!

http://raibledesigns.com

@mraible

Presentations

http://slideshare.net/mraible

Code

http://github.com/mra...
Who to follow on Twitter
AngularJS Team at Google

	 Miško Hevery - @mhevery

	 Igor Minar - @IgorMinar

	 Brian Ford - @b...
My Experience in 2013
Developing with AngularJS Series

Part I: The Basics

Part II: Dialogs and Data

Part III: Services
...
#dv13javaweb$
My Experience in 2013
http://vimeo.com/mraible/angularjs-deep-dive
2015 AngularJS Tutorials
Getting Started with AngularJS

http://raibledesigns.com/rd/entry/getting_started_with_angularjs ...
Spring and AngularJS http://spring.io/blog
http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-app...
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015
The Art of AngularJS in 2015 - Angular Summit 2015
Upcoming SlideShare
Loading in …5
×

The Art of AngularJS in 2015 - Angular Summit 2015

34,648 views

Published on

Presentation from Angular Summit Keynote in September 2015. http://angularsummit.com/conference/boston/2015/09/session?id=34212

AngularJS is one of today's hottest JavaScript MVC Frameworks. In this session, we'll explore many concepts it brings to the world of client-side development: dependency injection, directives, filters, routing and two-way data binding. We'll also look at its recommended testing tools and build systems.

Published in: Technology

The Art of AngularJS in 2015 - Angular Summit 2015

  1. 1. Photos by The Art of in 2015 Matt Raible • http://raibledesigns.com
  2. 2. Blogger on raibledesigns.com Founder of AppFuse Father, Skier, Mountain Biker, Whitewater Rafter Web Framework Connoisseur Who is Matt Raible? Bus Lover
  3. 3. How to Become an Artist Part 1 of 3: Learn the Basics on Your Own Take some time and try various mediums of art Recognize your strengths Do your research and learn the basics Get the supplies you will need Observe the world around you Make time for your art every day Seek out the opinions of others Develop your own style http://www.wikihow.com/Become-an-Artist
  4. 4. Jobs on Dice.com September 2015 0 500 1,000 1,500 2,000 Backbone Angular Em ber Knockout React
  5. 5. Job Growth 0 500 1000 1500 2000 February 2014 January 2015 September 2015 Ember.js AngularJS Backbone Knockout React
  6. 6. LinkedIn Skills September 2015 0 50,000 100,000 150,000 200,000 Backbone Angular Knockout Em ber React
  7. 7. LinkedIn Skills September 2015 0 15,000 30,000 45,000 60,000 Backbone Knockout Em ber React
  8. 8. Skills Growth 0 50000 100000 150000 200000 February 2014 January 2015 September 2015 Ember.js AngularJS Backbone Knockout React
  9. 9. Google Trends
  10. 10. Indeed Job Trends Absolute Relative
  11. 11. Stack Overflow
  12. 12. http://stackoverflow.com/research/developer-survey-2015
  13. 13. Who wants to learn ?
  14. 14. The History of AngularJS Started 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
  15. 15. The History of AngularJS 0 4500 9000 13500 18000 Lines of Code 17,000 1,000 AngularJS GWT
  16. 16. 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>
  17. 17. Architecture Principles Structure Testability Boilerplate D.R.Y.
  18. 18. Getting Started Start with Angular Seed git clone https://github.com/angular/angular-seed.git
  19. 19. App Definition var app = angular.module('myApp', []); <!DOCTYPE html> <html ng-app="myApp">
  20. 20. Model View Controller
  21. 21. Data Binding friend.js friend.html $scope.friend = { name: "Fernand" }; {{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way
  22. 22. Solving FOUC This 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>
  23. 23. Directives <div ng-repeat="entry in news.entries"> <span ng-bind="entry.title"></span> <button ng-click="delete($index)"> Delete </button> </div>
  24. 24. 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>
  25. 25. 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}}' }; });
  26. 26. Built-In Directives ng-href ng-src ng-disabled ng-checked ng-readonly ng-selected ng-class ng-style
  27. 27. Services var 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'}); });
  28. 28. $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);
  29. 29. $q myApp.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 }; });
  30. 30. $q myApp.controller('HelloCtrl', function($scope, HelloWorld) { HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; }); });
  31. 31. 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("/"); }); }; })
  32. 32. 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("/"); }); }; })
  33. 33. 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' }}
  34. 34. 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('!'); }] )
  35. 35. Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  36. 36. Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  37. 37. UI-Router angular.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' }) }])
  38. 38. ngRoute angular.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' }) }])
  39. 39. Testing Karma - test runner, framework agnostic Jasmine - unit tests, framework agnostic Protractor - integration tests, Angular-specific Lineman - productivity, framework agnostic
  40. 40. Testing: Controllers describe("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 }); }));
  41. 41. 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'); }); }); });
  42. 42. Testing: Directives beforeEach(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); }); });
  43. 43. Testing: Directives with CoffeeScript describe "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
  44. 44. 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"
  45. 45. 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);
  46. 46. 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"
  47. 47. Gruntfile.js module.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/**'] } },
  48. 48. 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' ]); };
  49. 49. 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>
  50. 50. 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>
  51. 51. After Grunt http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
  52. 52. You shouldn’t have to worry about FEO http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
  53. 53. HTTP/2 Performance Anti-Patterns? Split dominant content domains Reduce requests Merging Sprites DataURIs http://www.slideshare.net/andydavies
  54. 54. 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']);
  55. 55. UI Bootstrap: Carousel
  56. 56. 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>
  57. 57. Foundation for Apps http://foundation.zurb.com/apps
  58. 58. Foundation
  59. 59. 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']);
  60. 60. Ionic Framework http://ionicframework.com
  61. 61. #dv13javaweb$ My Ionic Experience http://raibledesigns.com/rd/entry/developing_an_ios_native_app
  62. 62. JHipster http://jhipster.github.io/
  63. 63. 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
  64. 64. JHipster
  65. 65. JHipster: Metrics
  66. 66. JHipster: Code Generation
  67. 67. JHipster: Code Generation
  68. 68. AngularJS Batarang
  69. 69. Angular 2.0 <input type="text" [value]="firstName"> <button (click)="addPerson()">Add</button> <input type="checkbox" [checked]="someProperty">
  70. 70. Concepts Eliminated in 2.0 Controllers Directive Definition Object $scope angular.module jqLite
  71. 71. The Bad News No 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
  72. 72. 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
  73. 73. Angular 1 to 2 Example
  74. 74. How to Become an Artist Part 1 of 3: Learn the Basics on Your Own Take some time and try various mediums of art Recognize your strengths Do your research and learn the basics Get the supplies you will need Observe the world around you Make time for your art every day Seek out the opinions of others Develop your own style http://www.wikihow.com/Become-an-Artist
  75. 75. Shortcut to becoming an Angular Artist JUST DO IT.
  76. 76. Contact Me! http://raibledesigns.com @mraible Presentations http://slideshare.net/mraible Code http://github.com/mraible Questions?
  77. 77. 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
  78. 78. My Experience in 2013 Developing with AngularJS Series Part I: The Basics
 Part II: Dialogs and Data
 Part III: Services
 Part IV: Making it Pop

  79. 79. #dv13javaweb$ My Experience in 2013 http://vimeo.com/mraible/angularjs-deep-dive
  80. 80. 2015 AngularJS Tutorials Getting Started with AngularJS http://raibledesigns.com/rd/entry/getting_started_with_angularjs Testing AngularJS Applications http://raibledesigns.com/rd/entry/testing_angularjs_applications
  81. 81. Spring and AngularJS http://spring.io/blog http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application

×