Photos by

The Art of in 2015
Matt Raible • http://raibledesigns.com
© 2014 Raible Designs
Blogger on raibledesigns.com
Founder of AppFuse
Father, Skier, Mountain
Biker, Whitewater Rafter
Web...
© 2015 Raible Designs
Devoxx4Kids Denver
• Teaching Kids to Program

• Java, Minecraft, robots, oh my!

• Non profit, looki...
© 2015 Raible Designs
How to Become an Artist
Part 1 of 3: Learn the Basics on Your Own

Take some time and try various me...
© 2015 Raible Designs
Jobs on Dice.com
January 2015
0
225
450
675
900
Backbone
Angular
Em
ber
Knockout
React
© 2015 Raible Designs
LinkedIn Skills
January 2015
0
25,000
50,000
75,000
100,000
Backbone
Angular
Knockout
Em
ber
React
© 2015 Raible Designs
Google Trends
© 2015 Raible Designs
Indeed Job Trends
Absolute
Relative
© 2015 Raible Designs
Stack Overflow
© 2015 Raible Designs
Who wants to learn ?
© 2015 Raible Designs
The History of AngularJS
Started by Miško Hevery in 2009

GWT = 3 developers, 6 months

AngularJS = ...
© 2015 Raible Designs
The History of AngularJS
0
4500
9000
13500
18000
Lines of Code
17,000
1,000
AngularJS GWT
© 2015 Raible Designs
Hello World
<!doctype html>
<html ng-app>
<head>
<title>Hello World</title>
</head>
<body>
<div>
<la...
© 2015 Raible Designs
Architecture Principles
Structure
Testability
Boilerplate
D.R.Y.
© 2015 Raible Designs
Code Organization
Start with Angular Seed*

* more options to be discussed later…
git clone https://...
© 2015 Raible Designs
Quick Demo
© 2015 Raible Designs
App Definition
var app = angular.module('myApp', []);
<!DOCTYPE html>
<html ng-app="myApp">
© 2015 Raible Designs
App Definition with separate files
app.js

controllers.js
angular.module('myApp', ['ngRoute',
'myApp.f...
© 2015 Raible Designs
Model View Controller
© 2015 Raible Designs
Data Binding
friend.js

friend.html

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

Use ng-cloak or ng-bind attrib...
© 2015 Raible Designs
Directives
<div ng-repeat="entry in news.entries">
<span ng-bind="entry.title"></span>
<button ng-cl...
© 2015 Raible Designs
Directives with valid HTML5
<div data-ng-repeat="entry in news.entries">
<span data-ng-bind="entry.t...
© 2015 Raible Designs
Custom Directives
$scope.customer = {
name: 'Franklin',
address: '1830 Blake'
};
<div ng-controller=...
© 2015 Raible Designs
Built-In Directives
ng-href

ng-src

ng-disabled

ng-checked

ng-readonly

ng-selected

ng-class

ng...
© 2015 Raible Designs
Services
var services = angular.module('myApp.services', ['ngResource']);
services.factory('LoginSer...
© 2015 Raible Designs
$http
$http({method: 'GET', url: '/news'}).
success(function(data, status, headers, config) {
// thi...
© 2015 Raible Designs
$q
myApp.factory('HelloWorld', function($q, $timeout) {
var getMessages = function() {
var deferred ...
© 2015 Raible Designs
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(functi...
© 2015 Raible Designs
Dependency Injection
.controller('LoginController', function($scope, $rootScope, $location,
$http, $...
© 2015 Raible Designs
Filters
also: lowercase, limitTo, orderBy
{{ name | uppercase }}
<!-- Displays: 123.46 -->
{{ 123.45...
© 2015 Raible Designs
Routes
.config(['$routeProvider', '$locationProvider', '$httpProvider',
function ($routeProvider, $l...
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults....
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults....
© 2015 Raible Designs
Code Organization Revisited
Lineman helps you build fat-client JavaScript apps

It produces happines...
Google's Recommendations for Angular App Structure
© 2015 Raible Designs
Testing
Karma - test runner, framework agnostic

Jasmine - unit tests, framework agnostic

Protracto...
© 2015 Raible Designs
Testing: Controllers
describe("controller: LoginController", function() {
beforeEach(function() {
mo...
© 2015 Raible Designs
Testing: Controllers
afterEach(function() {
this.$httpBackend.verifyNoOutstandingRequest();
this.$ht...
© 2015 Raible Designs
Testing: Directives
beforeEach(inject(function($rootScope, $compile) {
this.directiveMessage = 'ralp...
© 2015 Raible Designs
Testing: Directives with CoffeeScript
describe "directive: shows-message-when-hovered (coffeescript)...
© 2015 Raible Designs
Testing: End-to-End
protractor = require("protractor")
require "protractor/jasminewd"
require 'jasmi...
© 2015 Raible Designs
Building with Grunt
sudo npm install
sudo npm install -g grunt-cli
vi package.json
"grunt": "~0.4.1"...
© 2015 Raible Designs
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package...
© 2015 Raible Designs
Gruntfile.js
useminPrepare: {
html: 'app/index.html'
},
usemin: {
html: ['dist/index.html']
},
uglify...
© 2015 Raible Designs
Gruntfile.js
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// Tell Grunt what...
© 2015 Raible Designs
index.html comments
<head>
<title>My AngularJS App</title>
<!-- build:css css/seed.min.css -->
<link...
© 2015 Raible Designs
dist/index.html
<head>
<title>My AngularJS App</title>
<link rel="stylesheet" href="css/f050d0dc.see...
© 2015 Raible Designs
After Grunt
http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
© 2015 Raible Designs
You shouldn’t have to worry about FEO
http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
© 2015 Raible Designs
HTTP/2 Performance Anti-Patterns?
Split dominant content domains

Reduce requests

	 Merging

	 Spri...
© 2015 Raible Designs
UI Bootstrap http://angular-ui.github.io/bootstrap
<script src="lib/angular/ui-bootstrap-0.12.0.min....
© 2015 Raible Designs
UI Bootstrap: Carousel
© 2015 Raible Designs
UI Bootstrap: Carousel
<div ng-controller="CarouselDemoCtrl">
<div style="height: 305px">
<carousel ...
© 2015 Raible Designs
Foundation for Apps http://foundation.zurb.com/apps
© 2015 Raible Designs
Foundation
© 2015 Raible Designs
Foundation
© 2015 Raible Designs
Sass Mixins
<div class="row">
<main class="medium-9 columns">
<p>Main content</p>
</main>
<aside cla...
© 2015 Raible Designs
Sass Mixins
<div class="layout">
<main class="layout-content">
<p>Main content</p>
</main>
<aside cl...
© 2015 Raible Designs
Sass Mixins
http://bit.ly/1Kh1ha5
@import "foundation/components/grid";
.layout {
// `layout` contai...
© 2015 Raible Designs
Ionic Framework http://ionicframework.com
© 2015 Raible Designs#dv13javaweb$
My Ionic Experience
http://raibledesigns.com/rd/entry/developing_an_ios_native_app
© 2015 Raible Designs
JHipster http://jhipster.github.io/
© 2015 Raible Designs
JHipster
Spring Boot

Spring Security

AngularJS

Bootstrap

Bower

Metrics

Java 7 or Java 8

Maven...
© 2015 Raible Designs
JHipster
© 2015 Raible Designs
JHipster: Metrics
© 2015 Raible Designs
JHipster: Code Generation
© 2015 Raible Designs
JHipster: Code Generation
© 2015 Raible Designs
AngularJS Batarang
© 2015 Raible Designs
My Experience in 2013
Developing with AngularJS Series

Part I: The Basics

Part II: Dialogs and Dat...
© 2015 Raible Designs#dv13javaweb$
My Experience in 2013
http://vimeo.com/mraible/angularjs-deep-dive
© 2015 Raible Designs
2015 AngularJS Tutorials
Getting Started with AngularJS

http://raibledesigns.com/rd/entry/getting_s...
© 2015 Raible Designs
Spring and AngularJS http://spring.io/blog
http://spring.io/blog/2015/01/12/spring-and-angular-js-a-...
© 2015 Raible Designs
Angular 2.0
<input type="text" [value]="firstName">
<button (click)="addPerson()">Add</button>
<inpu...
© 2015 Raible Designs
Concepts Eliminated in 2.0
Controllers

Directive Definition Object

$scope

angular.module

jqLite
© 2015 Raible Designs
The Bad News
No migration path from Angular 1.x to 2.0

Angular 1.3 will be supported for 1.5 - 2 ye...
http://12factor.net/
© 2015 Raible Designs
How to Become an Artist
Part 1 of 3: Learn the Basics on Your Own

Take some time and try various me...
© 2015 Raible Designs
Shortcut to becoming an Angular Artist
JUST DO IT.
© 2015 Raible Designs
Contact Me!

http://raibledesigns.com

@mraible

Presentations

http://slideshare.net/mraible

Code
...
© 2015 Raible Designs
Who to follow on Twitter
AngularJS Team at Google

	 Miško Hevery - @mhevery

	 Igor Minar - @IgorMi...
© 2015 Raible Designs
Angular Dart

	 https://angulardart.org 

Devoxx AngularJS Talks on Parleys.com 

http://parleys.com...
© 2015 Raible Designs
Angular Seed

https://github.com/angular/angular-seed 

Lineman Application Template using AngularJS...
The Art of AngularJS in 2015
The Art of AngularJS in 2015
The Art of AngularJS in 2015
The Art of AngularJS in 2015
Próxima SlideShare
Cargando en…5
×

The Art of AngularJS in 2015

37.325 visualizaciones

Publicado el

Presentation from Denver Open Source Users Group in February 2015. http://www.meetup.com/DOSUG1/events/219099019/

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. Finally, you'll learn about my experience developing several real-world applications using AngularJS, HTML5 and Bootstrap.

Publicado en: Ingeniería, Software, Tecnología

The Art of AngularJS in 2015

  1. 1. Photos by The Art of in 2015 Matt Raible • http://raibledesigns.com
  2. 2. © 2014 Raible Designs Blogger on raibledesigns.com Founder of AppFuse Father, Skier, Mountain Biker, Whitewater Rafter Web Framework Connoisseur Who is Matt Raible? Bus Lover
  3. 3. © 2015 Raible Designs Devoxx4Kids Denver • Teaching Kids to Program • Java, Minecraft, robots, oh my! • Non profit, looking for donations and speakers http://www.meetup.com/Devoxx4Kids-Denver/
  4. 4. © 2015 Raible Designs 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
  5. 5. © 2015 Raible Designs Jobs on Dice.com January 2015 0 225 450 675 900 Backbone Angular Em ber Knockout React
  6. 6. © 2015 Raible Designs LinkedIn Skills January 2015 0 25,000 50,000 75,000 100,000 Backbone Angular Knockout Em ber React
  7. 7. © 2015 Raible Designs Google Trends
  8. 8. © 2015 Raible Designs Indeed Job Trends Absolute Relative
  9. 9. © 2015 Raible Designs Stack Overflow
  10. 10. © 2015 Raible Designs Who wants to learn ?
  11. 11. © 2015 Raible Designs 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
  12. 12. © 2015 Raible Designs The History of AngularJS 0 4500 9000 13500 18000 Lines of Code 17,000 1,000 AngularJS GWT
  13. 13. © 2015 Raible Designs 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.3.11/angular.min.js"></script> </body> </html>
  14. 14. © 2015 Raible Designs Architecture Principles Structure Testability Boilerplate D.R.Y.
  15. 15. © 2015 Raible Designs Code Organization Start with Angular Seed* * more options to be discussed later… git clone https://github.com/angular/angular-seed.git
  16. 16. © 2015 Raible Designs Quick Demo
  17. 17. © 2015 Raible Designs App Definition var app = angular.module('myApp', []); <!DOCTYPE html> <html ng-app="myApp">
  18. 18. © 2015 Raible Designs App Definition with separate files app.js controllers.js angular.module('myApp', ['ngRoute', 'myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers' ]) angular.module('myApp.controllers', []). controller('MyCtrl1', [function() { }])
  19. 19. © 2015 Raible Designs Model View Controller
  20. 20. © 2015 Raible Designs Data Binding friend.js friend.html $scope.friend = { name: "Fernand" }; {{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way
  21. 21. © 2015 Raible Designs 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>
  22. 22. © 2015 Raible Designs Directives <div ng-repeat="entry in news.entries"> <span ng-bind="entry.title"></span> <button ng-click="delete($index)"> Delete </button> </div>
  23. 23. © 2015 Raible Designs 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>
  24. 24. © 2015 Raible Designs 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}}' }; });
  25. 25. © 2015 Raible Designs Built-In Directives ng-href ng-src ng-disabled ng-checked ng-readonly ng-selected ng-class ng-style
  26. 26. © 2015 Raible Designs 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'}); });
  27. 27. © 2015 Raible Designs $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);
  28. 28. © 2015 Raible Designs $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 }; });
  29. 29. © 2015 Raible Designs $q myApp.controller('HelloCtrl', function($scope, HelloWorld) { HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; }); });
  30. 30. © 2015 Raible Designs 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("/"); }); }; })
  31. 31. © 2015 Raible Designs 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' }}
  32. 32. © 2015 Raible Designs 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('!'); }] )
  33. 33. © 2015 Raible Designs Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  34. 34. © 2015 Raible Designs Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  35. 35. © 2015 Raible Designs Code Organization Revisited Lineman helps you build fat-client JavaScript apps It produces happiness by building assets, mocking servers, and running specs on every file change git clone https://github.com/linemanjs/lineman-angular-template.git my-app cd my-app sudo npm install -g lineman npm install lineman run
  36. 36. Google's Recommendations for Angular App Structure
  37. 37. © 2015 Raible Designs Testing Karma - test runner, framework agnostic Jasmine - unit tests, framework agnostic Protractor - integration tests, angular specific Lineman - productivity, framework agnostic
  38. 38. © 2015 Raible Designs 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 }); }));
  39. 39. © 2015 Raible Designs 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'); }); }); });
  40. 40. © 2015 Raible Designs 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); }); });
  41. 41. © 2015 Raible Designs 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
  42. 42. © 2015 Raible Designs 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"
  43. 43. © 2015 Raible Designs Building with Grunt sudo npm install sudo npm install -g grunt-cli vi package.json "grunt": "~0.4.1", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-uglify": "~0.2.7", "grunt-contrib-cssmin": "~0.7.0", "grunt-usemin": "~2.0.2", "grunt-contrib-copy": "~0.5.0", "grunt-rev": "~0.1.0", "grunt-contrib-clean": "~0.5.0", "matchdep": "~0.3.0"
  44. 44. © 2015 Raible Designs Gruntfile.js module.exports = function (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}'] } },
  45. 45. © 2015 Raible Designs Gruntfile.js useminPrepare: { html: 'app/index.html' }, usemin: { html: ['dist/index.html'] }, uglify: { options: { report: 'min', mangle: false } } });
  46. 46. © 2015 Raible Designs Gruntfile.js require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks); // Tell Grunt what to do when we type "grunt" into the terminal grunt.registerTask('default', [ 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'rev', 'usemin' ]); };
  47. 47. © 2015 Raible Designs 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>
  48. 48. © 2015 Raible Designs 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>
  49. 49. © 2015 Raible Designs After Grunt http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
  50. 50. © 2015 Raible Designs You shouldn’t have to worry about FEO http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
  51. 51. © 2015 Raible Designs HTTP/2 Performance Anti-Patterns? Split dominant content domains Reduce requests Merging Sprites DataURIs http://www.slideshare.net/andydavies
  52. 52. © 2015 Raible Designs UI Bootstrap http://angular-ui.github.io/bootstrap <script src="lib/angular/ui-bootstrap-0.12.0.min.js"></script> <script src="lib/angular/ui-bootstrap-tpls-0.12.0.min.js"></script> angular.module('myApp', ['ui.bootstrap']);
  53. 53. © 2015 Raible Designs UI Bootstrap: Carousel
  54. 54. © 2015 Raible Designs 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>
  55. 55. © 2015 Raible Designs Foundation for Apps http://foundation.zurb.com/apps
  56. 56. © 2015 Raible Designs Foundation
  57. 57. © 2015 Raible Designs Foundation
  58. 58. © 2015 Raible Designs Sass Mixins <div class="row"> <main class="medium-9 columns"> <p>Main content</p> </main> <aside class="medium-3 columns"> <p>Sidebar</p> </aside> </div>
  59. 59. © 2015 Raible Designs Sass Mixins <div class="layout"> <main class="layout-content"> <p>Main content</p> </main> <aside class="layout-sidebar"> <p>Sidebar</p> </aside> </div>
  60. 60. © 2015 Raible Designs Sass Mixins http://bit.ly/1Kh1ha5 @import "foundation/components/grid"; .layout { // `layout` container functions as a row @include grid-row(); } .layout-content { // Mobile-first: make `layout-container` full-width @include grid-column(12); // On medium-up size, make `layout-container` 9 columns wide @media #{$medium-up} { @include grid-column(9); } } .layout-sidebar { // Mobile-first: make `layout-sidebar` full-width @include grid-column(12); // On medium-up size, make `layout-sidebar` 3 columns wide @media #{$medium-up} { @include grid-column(3); } }
  61. 61. © 2015 Raible Designs Ionic Framework http://ionicframework.com
  62. 62. © 2015 Raible Designs#dv13javaweb$ My Ionic Experience http://raibledesigns.com/rd/entry/developing_an_ios_native_app
  63. 63. © 2015 Raible Designs JHipster http://jhipster.github.io/
  64. 64. © 2015 Raible Designs 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
  65. 65. © 2015 Raible Designs JHipster
  66. 66. © 2015 Raible Designs JHipster: Metrics
  67. 67. © 2015 Raible Designs JHipster: Code Generation
  68. 68. © 2015 Raible Designs JHipster: Code Generation
  69. 69. © 2015 Raible Designs AngularJS Batarang
  70. 70. © 2015 Raible Designs 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

  71. 71. © 2015 Raible Designs#dv13javaweb$ My Experience in 2013 http://vimeo.com/mraible/angularjs-deep-dive
  72. 72. © 2015 Raible Designs 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
  73. 73. © 2015 Raible Designs Spring and AngularJS http://spring.io/blog http://spring.io/blog/2015/01/12/spring-and-angular-js-a-secure-single-page-application
  74. 74. © 2015 Raible Designs Angular 2.0 <input type="text" [value]="firstName"> <button (click)="addPerson()">Add</button> <input type="checkbox" [checked]="someProperty">
  75. 75. © 2015 Raible Designs Concepts Eliminated in 2.0 Controllers Directive Definition Object $scope angular.module jqLite
  76. 76. © 2015 Raible Designs 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
  77. 77. http://12factor.net/
  78. 78. © 2015 Raible Designs 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
  79. 79. © 2015 Raible Designs Shortcut to becoming an Angular Artist JUST DO IT.
  80. 80. © 2015 Raible Designs Contact Me! http://raibledesigns.com @mraible Presentations http://slideshare.net/mraible Code http://github.com/mraible Questions?
  81. 81. © 2015 Raible Designs 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
  82. 82. © 2015 Raible Designs Angular Dart https://angulardart.org Devoxx AngularJS Talks on Parleys.com http://parleys.com/play/5148922b0364bc17fc56c91b (2012) http://parleys.com/play/529321a5e4b054cd7d2ef4e1 (2013) Egghead.io - https://egghead.io/ Resources
  83. 83. © 2015 Raible Designs Angular Seed https://github.com/angular/angular-seed Lineman Application Template using AngularJS https://github.com/linemanjs/lineman-angular-template AngularJS + Rest + Spring Security https://github.com/joshlong/boot-examples/tree/master/x-auth-security Code

×