SlideShare ist ein Scribd-Unternehmen logo
1 von 87
Downloaden Sie, um offline zu lesen
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 Framework Connoisseur
Who is Matt Raible?
Bus Lover
© 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/
© 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
© 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 = 1 developer, 3 weeks

Learn more:

https://www.youtube.com/watch?v=X0VsStcCCM8
© 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>
<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>
© 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://github.com/angular/angular-seed.git
© 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.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
])
angular.module('myApp.controllers', []).
controller('MyCtrl1', [function() {
}])
© 2015 Raible Designs
Model View Controller
© 2015 Raible Designs
Data Binding
friend.js

friend.html

$scope.friend = {
name: "Fernand"
};
{{friend.name}} // 1-way
<input ng-model="friend.name"> // 2-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 attribute:

<p>{{friend.name}}</p>
<p ng-cloak>{{friend.name}}</p>
<p ng-bind="friend.name"></p>
© 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>
© 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>
© 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}}'
};
});
© 2015 Raible Designs
Built-In Directives
ng-href

ng-src

ng-disabled

ng-checked

ng-readonly

ng-selected

ng-class

ng-style
© 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'});
});
© 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);
© 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
};
});
© 2015 Raible Designs
$q
myApp.controller('HelloCtrl', function($scope, HelloWorld) {
HelloWorld.getMessages().then(function(messages) {
$scope.messages = messages;
});
});
© 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("/");
});
};
})
© 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' }}
© 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('!');
}]
)
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};
© 2015 Raible Designs
Routing: Navigation
$rootScope.logout = function () {
delete $rootScope.user;
delete $http.defaults.headers.common[xAuthTokenHeaderName];
$cookieStore.remove('user');
$location.path("/login");
};
© 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
Google's Recommendations for Angular App Structure
© 2015 Raible Designs
Testing
Karma - test runner, framework agnostic

Jasmine - unit tests, framework agnostic

Protractor - integration tests, angular specific

Lineman - productivity, framework agnostic
© 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
});
}));
© 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');
});
});
});
© 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);
});
});
© 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
© 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"
© 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"
© 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}']
}
},
© 2015 Raible Designs
Gruntfile.js
useminPrepare: {
html: 'app/index.html'
},
usemin: {
html: ['dist/index.html']
},
uglify: {
options: {
report: 'min',
mangle: false
}
}
});
© 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'
]);
};
© 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>
© 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>
© 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

	 Sprites

	 DataURIs
http://www.slideshare.net/andydavies
© 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']);
© 2015 Raible Designs
UI Bootstrap: Carousel
© 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>
© 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 class="medium-3 columns">
<p>Sidebar</p>
</aside>
</div>
© 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>
© 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);
}
}
© 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 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
© 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 Data

Part III: Services

Part IV: Making it Pop

© 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_started_with_angularjs 

Testing AngularJS Applications

http://raibledesigns.com/rd/entry/testing_angularjs_applications
© 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
© 2015 Raible Designs
Angular 2.0
<input type="text" [value]="firstName">
<button (click)="addPerson()">Add</button>
<input type="checkbox" [checked]="someProperty">
© 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 years

Will only support Evergreen Browsers (e.g. IE10+)

Learn more on

http://www.infoq.com/news/2014/10/angular-2-atscript
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 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
© 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

http://github.com/mraible
Questions?
© 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
© 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
© 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

Weitere ähnliche Inhalte

Was ist angesagt?

Building Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOSBuilding Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOS
FITC
 

Was ist angesagt? (20)

Real World Web components
Real World Web componentsReal World Web components
Real World Web components
 
The Art of Angular in 2016 - Devoxx UK 2016
The Art of Angular in 2016 - Devoxx UK 2016The Art of Angular in 2016 - Devoxx UK 2016
The Art of Angular in 2016 - Devoxx UK 2016
 
Gettings started with the superheroic JavaScript library AngularJS
Gettings started with the superheroic JavaScript library AngularJSGettings started with the superheroic JavaScript library AngularJS
Gettings started with the superheroic JavaScript library AngularJS
 
Testing Angular 2 Applications - HTML5 Denver 2016
Testing Angular 2 Applications - HTML5 Denver 2016Testing Angular 2 Applications - HTML5 Denver 2016
Testing Angular 2 Applications - HTML5 Denver 2016
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx UK 2016
 
Getting Started with Angular - Stormpath Webinar, January 2017
Getting Started with Angular - Stormpath Webinar, January 2017Getting Started with Angular - Stormpath Webinar, January 2017
Getting Started with Angular - Stormpath Webinar, January 2017
 
Web Components
Web ComponentsWeb Components
Web Components
 
Great Responsive-ability Web Design
Great Responsive-ability Web DesignGreat Responsive-ability Web Design
Great Responsive-ability Web Design
 
What's New in Spring 3.1
What's New in Spring 3.1What's New in Spring 3.1
What's New in Spring 3.1
 
Accessibility - A feature you can build
Accessibility - A feature you can buildAccessibility - A feature you can build
Accessibility - A feature you can build
 
Web Frameworks of the Future: Flex, GWT, Grails and Rails
Web Frameworks of the Future: Flex, GWT, Grails and RailsWeb Frameworks of the Future: Flex, GWT, Grails and Rails
Web Frameworks of the Future: Flex, GWT, Grails and Rails
 
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
Get Hip with JHipster - Colorado Springs OSS Meetup April 2016
 
The Art of AngularJS - DeRailed 2014
The Art of AngularJS - DeRailed 2014The Art of AngularJS - DeRailed 2014
The Art of AngularJS - DeRailed 2014
 
Real World Web Standards
Real World Web StandardsReal World Web Standards
Real World Web Standards
 
Java Web Application Security - Denver JUG 2013
Java Web Application Security - Denver JUG 2013Java Web Application Security - Denver JUG 2013
Java Web Application Security - Denver JUG 2013
 
The Complementarity of React and Web Components
The Complementarity of React and Web ComponentsThe Complementarity of React and Web Components
The Complementarity of React and Web Components
 
Chrome enchanted 2015
Chrome enchanted 2015Chrome enchanted 2015
Chrome enchanted 2015
 
Building Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOSBuilding Progressive Web Apps for Android and iOS
Building Progressive Web Apps for Android and iOS
 
Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with Ionic
 

Andere mochten auch

Andere mochten auch (11)

CSS3 Media Queries
CSS3 Media QueriesCSS3 Media Queries
CSS3 Media Queries
 
Beyond Media Queries: Anatomy of an Adaptive Web Design
Beyond Media Queries: Anatomy of an Adaptive Web DesignBeyond Media Queries: Anatomy of an Adaptive Web Design
Beyond Media Queries: Anatomy of an Adaptive Web Design
 
Media queries and frameworks
Media queries and frameworksMedia queries and frameworks
Media queries and frameworks
 
AngularJS best practices
AngularJS best practicesAngularJS best practices
AngularJS best practices
 
AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
 
AngularJS best-practices
AngularJS best-practicesAngularJS best-practices
AngularJS best-practices
 
Mobile Email Design, Strategies, Workflow and Best Practices
Mobile Email Design, Strategies, Workflow and Best PracticesMobile Email Design, Strategies, Workflow and Best Practices
Mobile Email Design, Strategies, Workflow and Best Practices
 
CSS Best practice
CSS Best practiceCSS Best practice
CSS Best practice
 
New Features in Angular 1.5
New Features in Angular 1.5New Features in Angular 1.5
New Features in Angular 1.5
 
Css best practices style guide and tips
Css best practices style guide and tipsCss best practices style guide and tips
Css best practices style guide and tips
 
AngularJS Best Practices
AngularJS Best PracticesAngularJS Best Practices
AngularJS Best Practices
 

Ähnlich wie The Art of AngularJS in 2015

15 Drupal Modules You've Probably Overlooked but Shouldn't
15 Drupal Modules You've Probably Overlooked but Shouldn't15 Drupal Modules You've Probably Overlooked but Shouldn't
15 Drupal Modules You've Probably Overlooked but Shouldn't
Chris Sloan
 

Ähnlich wie The Art of AngularJS in 2015 (20)

Utilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done FasterUtilizing jQuery in SharePoint: Get More Done Faster
Utilizing jQuery in SharePoint: Get More Done Faster
 
The Art of Angular in 2016 - Devoxx France 2016
The Art of Angular in 2016 - Devoxx France 2016The Art of Angular in 2016 - Devoxx France 2016
The Art of Angular in 2016 - Devoxx France 2016
 
Going web native
Going web nativeGoing web native
Going web native
 
The Modern Java Web Developer - Denver JUG 2013
The Modern Java Web Developer - Denver JUG 2013The Modern Java Web Developer - Denver JUG 2013
The Modern Java Web Developer - Denver JUG 2013
 
Adobe & HTML5
Adobe & HTML5Adobe & HTML5
Adobe & HTML5
 
WordPress Accessibility: WordCamp Chicago
WordPress Accessibility: WordCamp ChicagoWordPress Accessibility: WordCamp Chicago
WordPress Accessibility: WordCamp Chicago
 
New Perspectives on Performance
New Perspectives on PerformanceNew Perspectives on Performance
New Perspectives on Performance
 
Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017Front End Development for Back End Developers - Denver Startup Week 2017
Front End Development for Back End Developers - Denver Startup Week 2017
 
The Art of Angular in 2016 - vJUG24
The Art of Angular in 2016 - vJUG24The Art of Angular in 2016 - vJUG24
The Art of Angular in 2016 - vJUG24
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in Production
 
Tulsa TechFest 2015 Awesomely Simple SharePoint Solutions
Tulsa TechFest 2015 Awesomely Simple SharePoint SolutionsTulsa TechFest 2015 Awesomely Simple SharePoint Solutions
Tulsa TechFest 2015 Awesomely Simple SharePoint Solutions
 
Headless Drupal
Headless DrupalHeadless Drupal
Headless Drupal
 
Twitter bootstrap on rails
Twitter bootstrap on railsTwitter bootstrap on rails
Twitter bootstrap on rails
 
Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018Vaadin Flow - JavaLand 2018
Vaadin Flow - JavaLand 2018
 
RWD in the Wild
RWD in the WildRWD in the Wild
RWD in the Wild
 
Introduction to Ruby on Rails
Introduction to Ruby on RailsIntroduction to Ruby on Rails
Introduction to Ruby on Rails
 
15 Drupal Modules You've Probably Overlooked but Shouldn't
15 Drupal Modules You've Probably Overlooked but Shouldn't15 Drupal Modules You've Probably Overlooked but Shouldn't
15 Drupal Modules You've Probably Overlooked but Shouldn't
 
Ruby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter BootstrapRuby on Rails + AngularJS + Twitter Bootstrap
Ruby on Rails + AngularJS + Twitter Bootstrap
 
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
JavaScripters Event Oct 22, 2016 · 2:00 PM: Common Mistakes made by Angular D...
 
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJSAngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
 

Mehr von Matt Raible

Mehr von Matt Raible (20)

Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
Keep Identities in Sync the SCIMple Way - ApacheCon NA 2022
 
Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022Micro Frontends for Java Microservices - Belfast JUG 2022
Micro Frontends for Java Microservices - Belfast JUG 2022
 
Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022Micro Frontends for Java Microservices - Dublin JUG 2022
Micro Frontends for Java Microservices - Dublin JUG 2022
 
Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022Micro Frontends for Java Microservices - Cork JUG 2022
Micro Frontends for Java Microservices - Cork JUG 2022
 
Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022Comparing Native Java REST API Frameworks - Seattle JUG 2022
Comparing Native Java REST API Frameworks - Seattle JUG 2022
 
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
 
Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022Comparing Native Java REST API Frameworks - Devoxx France 2022
Comparing Native Java REST API Frameworks - Devoxx France 2022
 
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
Lock That Sh*t Down! Auth Security Patterns for Apps, APIs, and Infra - Devne...
 
Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021Native Java with Spring Boot and JHipster - Garden State JUG 2021
Native Java with Spring Boot and JHipster - Garden State JUG 2021
 
Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021Java REST API Framework Comparison - PWX 2021
Java REST API Framework Comparison - PWX 2021
 
Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021Web App Security for Java Developers - PWX 2021
Web App Security for Java Developers - PWX 2021
 
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
Mobile App Development with Ionic, React Native, and JHipster - Connect.Tech ...
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Joker...
 
Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021Web App Security for Java Developers - UberConf 2021
Web App Security for Java Developers - UberConf 2021
 
Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021Java REST API Framework Comparison - UberConf 2021
Java REST API Framework Comparison - UberConf 2021
 
Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021Native Java with Spring Boot and JHipster - SF JUG 2021
Native Java with Spring Boot and JHipster - SF JUG 2021
 
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
Lock That Shit Down! Auth Security Patterns for Apps, APIs, and Infra - Sprin...
 
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
Reactive Java Microservices with Spring Boot and JHipster - Denver JUG 2021
 
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021Get Hip with JHipster - Colorado Springs Open Source User Group 2021
Get Hip with JHipster - Colorado Springs Open Source User Group 2021
 
JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020JHipster and Okta - JHipster Virtual Meetup December 2020
JHipster and Okta - JHipster Virtual Meetup December 2020
 

Kürzlich hochgeladen

Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Kürzlich hochgeladen (20)

Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank  Design by Working Stress - IS Method.pdfIntze Overhead Water Tank  Design by Working Stress - IS Method.pdf
Intze Overhead Water Tank Design by Working Stress - IS Method.pdf
 
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...Booking open Available Pune Call Girls Koregaon Park  6297143586 Call Hot Ind...
Booking open Available Pune Call Girls Koregaon Park 6297143586 Call Hot Ind...
 
UNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its PerformanceUNIT - IV - Air Compressors and its Performance
UNIT - IV - Air Compressors and its Performance
 
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
Call Girls Pimpri Chinchwad Call Me 7737669865 Budget Friendly No Advance Boo...
 
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
The Most Attractive Pune Call Girls Manchar 8250192130 Will You Miss This Cha...
 
Unit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdfUnit 1 - Soil Classification and Compaction.pdf
Unit 1 - Soil Classification and Compaction.pdf
 
Thermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.pptThermal Engineering -unit - III & IV.ppt
Thermal Engineering -unit - III & IV.ppt
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
VIP Model Call Girls Kothrud ( Pune ) Call ON 8005736733 Starting From 5K to ...
 
chapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineeringchapter 5.pptx: drainage and irrigation engineering
chapter 5.pptx: drainage and irrigation engineering
 
NFPA 5000 2024 standard .
NFPA 5000 2024 standard                                  .NFPA 5000 2024 standard                                  .
NFPA 5000 2024 standard .
 
Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01Double rodded leveling 1 pdf activity 01
Double rodded leveling 1 pdf activity 01
 
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar  ≼🔝 Delhi door step de...
Call Now ≽ 9953056974 ≼🔝 Call Girls In New Ashok Nagar ≼🔝 Delhi door step de...
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
(INDIRA) Call Girl Bhosari Call Now 8617697112 Bhosari Escorts 24x7
 
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance BookingCall Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
Call Girls Wakad Call Me 7737669865 Budget Friendly No Advance Booking
 
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
The Most Attractive Pune Call Girls Budhwar Peth 8250192130 Will You Miss Thi...
 
Roadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and RoutesRoadmap to Membership of RICS - Pathways and Routes
Roadmap to Membership of RICS - Pathways and Routes
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 

The Art of AngularJS in 2015

  • 1. Photos by The Art of in 2015 Matt Raible • http://raibledesigns.com
  • 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. © 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. © 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. © 2015 Raible Designs Jobs on Dice.com January 2015 0 225 450 675 900 Backbone Angular Em ber Knockout React
  • 6. © 2015 Raible Designs LinkedIn Skills January 2015 0 25,000 50,000 75,000 100,000 Backbone Angular Knockout Em ber React
  • 7. © 2015 Raible Designs Google Trends
  • 8. © 2015 Raible Designs Indeed Job Trends Absolute Relative
  • 9. © 2015 Raible Designs Stack Overflow
  • 10.
  • 11. © 2015 Raible Designs Who wants to learn ?
  • 12. © 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
  • 13. © 2015 Raible Designs The History of AngularJS 0 4500 9000 13500 18000 Lines of Code 17,000 1,000 AngularJS GWT
  • 14. © 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>
  • 15. © 2015 Raible Designs Architecture Principles Structure Testability Boilerplate D.R.Y.
  • 16. © 2015 Raible Designs Code Organization Start with Angular Seed* * more options to be discussed later… git clone https://github.com/angular/angular-seed.git
  • 17. © 2015 Raible Designs Quick Demo
  • 18. © 2015 Raible Designs App Definition var app = angular.module('myApp', []); <!DOCTYPE html> <html ng-app="myApp">
  • 19. © 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() { }])
  • 20. © 2015 Raible Designs Model View Controller
  • 21. © 2015 Raible Designs Data Binding friend.js friend.html $scope.friend = { name: "Fernand" }; {{friend.name}} // 1-way <input ng-model="friend.name"> // 2-way
  • 22. © 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>
  • 23. © 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>
  • 24. © 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>
  • 25. © 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}}' }; });
  • 26. © 2015 Raible Designs Built-In Directives ng-href ng-src ng-disabled ng-checked ng-readonly ng-selected ng-class ng-style
  • 27. © 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'}); });
  • 28. © 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);
  • 29. © 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 }; });
  • 30. © 2015 Raible Designs $q myApp.controller('HelloCtrl', function($scope, HelloWorld) { HelloWorld.getMessages().then(function(messages) { $scope.messages = messages; }); });
  • 31. © 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("/"); }); }; })
  • 32. © 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' }}
  • 33. © 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('!'); }] )
  • 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. © 2015 Raible Designs Routing: Navigation $rootScope.logout = function () { delete $rootScope.user; delete $http.defaults.headers.common[xAuthTokenHeaderName]; $cookieStore.remove('user'); $location.path("/login"); };
  • 36. © 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
  • 37.
  • 38.
  • 39. Google's Recommendations for Angular App Structure
  • 40.
  • 41. © 2015 Raible Designs Testing Karma - test runner, framework agnostic Jasmine - unit tests, framework agnostic Protractor - integration tests, angular specific Lineman - productivity, framework agnostic
  • 42. © 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 }); }));
  • 43. © 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'); }); }); });
  • 44. © 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); }); });
  • 45. © 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
  • 46. © 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"
  • 47. © 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"
  • 48. © 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}'] } },
  • 49. © 2015 Raible Designs Gruntfile.js useminPrepare: { html: 'app/index.html' }, usemin: { html: ['dist/index.html'] }, uglify: { options: { report: 'min', mangle: false } } });
  • 50. © 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' ]); };
  • 51. © 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>
  • 52. © 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>
  • 53. © 2015 Raible Designs After Grunt http://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for
  • 54. © 2015 Raible Designs You shouldn’t have to worry about FEO http://raibledesigns.com/rd/entry/you_shouldn_t_have_to
  • 55. © 2015 Raible Designs HTTP/2 Performance Anti-Patterns? Split dominant content domains Reduce requests Merging Sprites DataURIs http://www.slideshare.net/andydavies
  • 56. © 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']);
  • 57. © 2015 Raible Designs UI Bootstrap: Carousel
  • 58. © 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>
  • 59. © 2015 Raible Designs Foundation for Apps http://foundation.zurb.com/apps
  • 60. © 2015 Raible Designs Foundation
  • 61. © 2015 Raible Designs Foundation
  • 62. © 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>
  • 63. © 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>
  • 64. © 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); } }
  • 65. © 2015 Raible Designs Ionic Framework http://ionicframework.com
  • 66. © 2015 Raible Designs#dv13javaweb$ My Ionic Experience http://raibledesigns.com/rd/entry/developing_an_ios_native_app
  • 67. © 2015 Raible Designs JHipster http://jhipster.github.io/
  • 68. © 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
  • 69. © 2015 Raible Designs JHipster
  • 70. © 2015 Raible Designs JHipster: Metrics
  • 71. © 2015 Raible Designs JHipster: Code Generation
  • 72. © 2015 Raible Designs JHipster: Code Generation
  • 73. © 2015 Raible Designs AngularJS Batarang
  • 74. © 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

  • 75. © 2015 Raible Designs#dv13javaweb$ My Experience in 2013 http://vimeo.com/mraible/angularjs-deep-dive
  • 76. © 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
  • 77. © 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
  • 78. © 2015 Raible Designs Angular 2.0 <input type="text" [value]="firstName"> <button (click)="addPerson()">Add</button> <input type="checkbox" [checked]="someProperty">
  • 79. © 2015 Raible Designs Concepts Eliminated in 2.0 Controllers Directive Definition Object $scope angular.module jqLite
  • 80. © 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
  • 82. © 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
  • 83. © 2015 Raible Designs Shortcut to becoming an Angular Artist JUST DO IT.
  • 84. © 2015 Raible Designs Contact Me! http://raibledesigns.com @mraible Presentations http://slideshare.net/mraible Code http://github.com/mraible Questions?
  • 85. © 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
  • 86. © 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
  • 87. © 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