際際滷

際際滷Share a Scribd company logo
AngularJS for Java 
Developers 
Loc Nguyen 
lochnguyen@gmail.com
<ng-selfie/> 
 Organizer of AngularJS-OC [angularjsoc.org, @angularjsoc] 
 Multi-platform SW geek => Java, Ruby, JavaScript, C#, Node 
 First an Ember fan (still am) 
 ~1.5 years of AngularJS experience => mostly consulting
Agenda 
 Thick client history 
 Current state of JS 
 MVC & Data binding 
 Components 
 Tooling 
 Resources
How to train your dragon JavaScript
Ship It
Ambitious Web Applications
AngularJS for Java Developers
AngularJS for Java Developers
AngularJS for Java Developers
AngularJS for Java Developers
The Model 
 Plain old Java(Script) objects  POJO! 
 No need to extend a hierarchy
class Member { 
String name = ""; 
boolean active = true; 
List<String> emails = new List<String>(); 
} 
var member = { 
name: '', 
active: true, 
emails: [] 
};
The View 
 Just plain HTML 
 Built-in directives similar to JSTL
// index.jsp 
<c:if test="${member.active}"> 
<c:out value="${member.name}"/> 
<ul> 
<c:forEach items="${member.emails}" var="email"> 
<li><c:out value="${email}"/></li> 
</c:forEach> 
</ul> 
</c:if> 
// index.html 
<div ng-if="member.active"> 
{{member.name}} 
<ul> 
<li ng-repeat="email in member.emails"> 
{{email}} 
</li> 
</ul> 
</div>
The Controller 
 Plain old JavaScript functions 
 Instantiated as needed 
 Inject dependencies 
 Figure out what the view needs, defer retrieval 
 $scope is the context 
o a view model
package ocjug.controllers; 
@Controller 
class MeetupController { 
function meetupController($scope) { 
$scope.person = { 
name: 'Loc', active: true, emails: [...] 
}; 
} 
public String index(Model model) { 
Member person = new Member(); 
member.name = "Loc"; 
member.active = true; 
member.emails = Arrays.asList(...); 
model.setAttribute("scope", member); 
} 
} 
angular.module('ocjug.controllers', []) 
.controller('MeetupController', meetupController);
Data Binding 
 $digest loop  Angular event loop 
 $watch list  whats dirty? 
 http://codepen.io/anon/pen/EcoGd
Dependency Injection 
 Code to abstractions 
 Testing is so easy 
 SOLID 
 Put controllers on a diet
Services 
 Promote cleaner code 
 Organization and reusability 
 Shared business logic 
 Data retrieval 
 One instance in app 
 3 ways to make a service!
package ocjug.services; 
@Service 
class MeetupSearchService { 
private final API_KEY = "abc123"; 
private final SEARCH_URI = "https://api.meetup.com/search"; 
@Autowired 
SomeHttpClient httpClient; 
public List<SearchResult> search(Map params) { 
// start pseudo-ing 
httpClient.queryParams(params).get(SEARCH_URI); 
} 
} 
Example
angular.module('ocjug.services', []) 
.factory('MeetupSearchSvc', function ($http) { 
var API_KEY = 'abc123'; 
var SEARCH_URI = 'https://api.meetup.com/search'; 
var search = function (queryParams) { 
return $http.get(SEARCH_URI, { params: queryParams 
}); 
}; 
return { 
search: search 
} 
});
Services 
.service() - invoke with the new keyword 
angular.module('ocjug.services', []) 
.service('MeetupSearchService', function ($http) { 
this.API = 'http://api.meetup.com/search'; 
this.search = function() { 
// ... 
} 
});
Services (cont) 
.factory() - always use a factory! 
angular.module('ocjug.services', []) 
.factory('MeetupSearchService', function ($http) { 
var API = 'http://api.meetup.com/search'; 
return { 
search: function (params) { 
//  
} 
}; 
});
Services (cont) 
.provider() - configure before app starts 
angular.module('ocjug.services', []) 
.provider('MeetupSearchProvider', function () { 
var API = 'http://api.meetup.com/search'; 
this.REMEMBER_SEARCHES = false; 
this.$get = function ($http) { 
return { 
search: function (params) { 
//  
if (this.REMEMBER_SEARCHES) ... 
} 
}; 
}; 
});
Services (cont) 
angular.module('ocjug', ['ocjug.services']) 
.config(function(MeetupSearchProviderProvider) { 
MeetupSearchProviderProvider.REMEMBER_SEARCHES = true; 
});
angular.module('ocjug.controllers', []) 
.controller('MemberSearchCtrl', function ($scope, $http) { 
$http.get('http://api.meetup.com/search?name=' + 
$scope.name); 
}) 
.controller('MeetupSearchCtrl', function ($scope, $http) { 
$http.get('http://api.meetup.com/search?meetup=' 
+ $scope.meetup); 
}); 
Extracting into a Service
var ocjug = angular.module('ocjug', ['ocjug.services']); 
function memberSearchCtrl ($scope, MeetupSearchSvc) { 
MeetupSearchSvc.search({ name: $scope.name }); 
} 
ocjug.controller(MemberSearchCtrl, memberSearchCtrl); 
function meetupSearchCtrl ($scope, MeetupSearchSvc) { 
MeetupSearchSvc.search({ meetup: $scope.meetup }); 
} 
ocjug.controller(MeetupSearchCtrl, meetupSearchCtrl);
Filters 
 Take an input to filter 
 Easily format data in templates 
 Uses the | character in {{ }} expression 
{{1.456 | number:2}} => 1.46 
{{'ocjug'| uppercase | limitTo:3}} => OCJ 
{{99.99 | currency:'USD$' }} => USD$99.99 
<div ng-repeat="m in movies | orderBy:'revenue'">
angular.module('ocjug.filters', []) 
.filter('asCentimeters', function () { 
return function (inches) { 
return inches * 2.54; 
}; 
}); 
{{2 | asCentimeters}} => 5.08
Directives 
 The killer feature of AngularJS 
 ...and the most complex API 
 Apply liberally
Directives 
 Built-in directives 
 ng-show, ng-click, ng-repeat 
 Custom directives 
 reusable widgets 
 declarative programming 
 wrap non Angular libraries
<div ng-repeat="picture in pictures"> 
<pic picture="picture" 
commentable="{{picture.approved}}"></pic> 
</div>
// picture.tpl.html 
<div> 
<img ng-src=/slideshow/angular-js-for-java-developers-40120787/40120787/"picture.url"/> 
<div>{{picture.caption}}</div> 
<a ng-click="fbLike(picture)">Like</a> 
<ul> 
<li ng-repeat="comment in picture.comments | 
limitTo:3"> 
{{comment}} 
</li> 
</ul> 
<comment-form picture="picture">  </comment-form> 
</div>
angular.module(ocjug.directives, ['ocjug.services']) 
.directive('pic', function(FbService) { 
return { 
templateUrl: 'picture.tpl.html', 
scope: { 
picture: '=', 
commentable: '@' 
}, 
link: function ($scope, el, attrs) { 
$scope.fbLike = function(picture) { 
FbService.like(picture.id); 
} 
} 
} 
});
angular.module(ocjug.directives, ['ocjug.services]) 
.directive('commentForm', function(CommentService) { 
return { 
templateUrl: 'comment.tpl.html', 
scope: { 
picture: '=' 
}, 
link: function ($scope, el, attrs) { 
$scope.submit = function(comment) { 
CommentService.create(comment); 
} 
} 
} 
});
Test and Tools 
 Unit tests - Karma 
 E2E - Protractor 
 Node based build tools 
o Grunt 
o Gulp
Whats missing? 
 SPA vs Islands of Richness 
 Async and promises 
 AJAX 
 Performance 
 Routing 
 Testing 
 Mobile 
 Integration
Resources 
UI-Router: github.com/angular-ui/ui-router 
Angular-UI: github.com/angular-ui 
Ionic: ionicframework.com 
Year of Moo: yearofmoo.com 
Style Guide: github.com/johnpapa/angularjs-styleguide
docs.angularjs.org/tutorial 
 Free! 
 Beginner
codeschool.com 
 Free! 
 Gamified learning 
 Beginner
egghead.io 
 AngularJS, 
 JavaScript, 
 D3.js 
 EcmaScript 6 
 NodeJS 
 ReactJS 
 $10m or $100/y 
https://egghead.io/pricing?dc=ng_socal 
Beginner  Advanced
pluralsight.com 
 $29 month 
 The most Angular courses 
 Deep coverage of JS 
 ...and .NET 
 Beginner  Advanced
$40 $23
AngularJS for Java Developers
angularjsoc.org 
meetup.com/AngularJS-OC

More Related Content

AngularJS for Java Developers

  • 1. AngularJS for Java Developers Loc Nguyen lochnguyen@gmail.com
  • 2. <ng-selfie/> Organizer of AngularJS-OC [angularjsoc.org, @angularjsoc] Multi-platform SW geek => Java, Ruby, JavaScript, C#, Node First an Ember fan (still am) ~1.5 years of AngularJS experience => mostly consulting
  • 3. Agenda Thick client history Current state of JS MVC & Data binding Components Tooling Resources
  • 4. How to train your dragon JavaScript
  • 11. The Model Plain old Java(Script) objects POJO! No need to extend a hierarchy
  • 12. class Member { String name = ""; boolean active = true; List<String> emails = new List<String>(); } var member = { name: '', active: true, emails: [] };
  • 13. The View Just plain HTML Built-in directives similar to JSTL
  • 14. // index.jsp <c:if test="${member.active}"> <c:out value="${member.name}"/> <ul> <c:forEach items="${member.emails}" var="email"> <li><c:out value="${email}"/></li> </c:forEach> </ul> </c:if> // index.html <div ng-if="member.active"> {{member.name}} <ul> <li ng-repeat="email in member.emails"> {{email}} </li> </ul> </div>
  • 15. The Controller Plain old JavaScript functions Instantiated as needed Inject dependencies Figure out what the view needs, defer retrieval $scope is the context o a view model
  • 16. package ocjug.controllers; @Controller class MeetupController { function meetupController($scope) { $scope.person = { name: 'Loc', active: true, emails: [...] }; } public String index(Model model) { Member person = new Member(); member.name = "Loc"; member.active = true; member.emails = Arrays.asList(...); model.setAttribute("scope", member); } } angular.module('ocjug.controllers', []) .controller('MeetupController', meetupController);
  • 17. Data Binding $digest loop Angular event loop $watch list whats dirty? http://codepen.io/anon/pen/EcoGd
  • 18. Dependency Injection Code to abstractions Testing is so easy SOLID Put controllers on a diet
  • 19. Services Promote cleaner code Organization and reusability Shared business logic Data retrieval One instance in app 3 ways to make a service!
  • 20. package ocjug.services; @Service class MeetupSearchService { private final API_KEY = "abc123"; private final SEARCH_URI = "https://api.meetup.com/search"; @Autowired SomeHttpClient httpClient; public List<SearchResult> search(Map params) { // start pseudo-ing httpClient.queryParams(params).get(SEARCH_URI); } } Example
  • 21. angular.module('ocjug.services', []) .factory('MeetupSearchSvc', function ($http) { var API_KEY = 'abc123'; var SEARCH_URI = 'https://api.meetup.com/search'; var search = function (queryParams) { return $http.get(SEARCH_URI, { params: queryParams }); }; return { search: search } });
  • 22. Services .service() - invoke with the new keyword angular.module('ocjug.services', []) .service('MeetupSearchService', function ($http) { this.API = 'http://api.meetup.com/search'; this.search = function() { // ... } });
  • 23. Services (cont) .factory() - always use a factory! angular.module('ocjug.services', []) .factory('MeetupSearchService', function ($http) { var API = 'http://api.meetup.com/search'; return { search: function (params) { // } }; });
  • 24. Services (cont) .provider() - configure before app starts angular.module('ocjug.services', []) .provider('MeetupSearchProvider', function () { var API = 'http://api.meetup.com/search'; this.REMEMBER_SEARCHES = false; this.$get = function ($http) { return { search: function (params) { // if (this.REMEMBER_SEARCHES) ... } }; }; });
  • 25. Services (cont) angular.module('ocjug', ['ocjug.services']) .config(function(MeetupSearchProviderProvider) { MeetupSearchProviderProvider.REMEMBER_SEARCHES = true; });
  • 26. angular.module('ocjug.controllers', []) .controller('MemberSearchCtrl', function ($scope, $http) { $http.get('http://api.meetup.com/search?name=' + $scope.name); }) .controller('MeetupSearchCtrl', function ($scope, $http) { $http.get('http://api.meetup.com/search?meetup=' + $scope.meetup); }); Extracting into a Service
  • 27. var ocjug = angular.module('ocjug', ['ocjug.services']); function memberSearchCtrl ($scope, MeetupSearchSvc) { MeetupSearchSvc.search({ name: $scope.name }); } ocjug.controller(MemberSearchCtrl, memberSearchCtrl); function meetupSearchCtrl ($scope, MeetupSearchSvc) { MeetupSearchSvc.search({ meetup: $scope.meetup }); } ocjug.controller(MeetupSearchCtrl, meetupSearchCtrl);
  • 28. Filters Take an input to filter Easily format data in templates Uses the | character in {{ }} expression {{1.456 | number:2}} => 1.46 {{'ocjug'| uppercase | limitTo:3}} => OCJ {{99.99 | currency:'USD$' }} => USD$99.99 <div ng-repeat="m in movies | orderBy:'revenue'">
  • 29. angular.module('ocjug.filters', []) .filter('asCentimeters', function () { return function (inches) { return inches * 2.54; }; }); {{2 | asCentimeters}} => 5.08
  • 30. Directives The killer feature of AngularJS ...and the most complex API Apply liberally
  • 31. Directives Built-in directives ng-show, ng-click, ng-repeat Custom directives reusable widgets declarative programming wrap non Angular libraries
  • 32. <div ng-repeat="picture in pictures"> <pic picture="picture" commentable="{{picture.approved}}"></pic> </div>
  • 33. // picture.tpl.html <div> <img ng-src=/slideshow/angular-js-for-java-developers-40120787/40120787/"picture.url"/> <div>{{picture.caption}}</div> <a ng-click="fbLike(picture)">Like</a> <ul> <li ng-repeat="comment in picture.comments | limitTo:3"> {{comment}} </li> </ul> <comment-form picture="picture"> </comment-form> </div>
  • 34. angular.module(ocjug.directives, ['ocjug.services']) .directive('pic', function(FbService) { return { templateUrl: 'picture.tpl.html', scope: { picture: '=', commentable: '@' }, link: function ($scope, el, attrs) { $scope.fbLike = function(picture) { FbService.like(picture.id); } } } });
  • 35. angular.module(ocjug.directives, ['ocjug.services]) .directive('commentForm', function(CommentService) { return { templateUrl: 'comment.tpl.html', scope: { picture: '=' }, link: function ($scope, el, attrs) { $scope.submit = function(comment) { CommentService.create(comment); } } } });
  • 36. Test and Tools Unit tests - Karma E2E - Protractor Node based build tools o Grunt o Gulp
  • 37. Whats missing? SPA vs Islands of Richness Async and promises AJAX Performance Routing Testing Mobile Integration
  • 38. Resources UI-Router: github.com/angular-ui/ui-router Angular-UI: github.com/angular-ui Ionic: ionicframework.com Year of Moo: yearofmoo.com Style Guide: github.com/johnpapa/angularjs-styleguide
  • 40. codeschool.com Free! Gamified learning Beginner
  • 41. egghead.io AngularJS, JavaScript, D3.js EcmaScript 6 NodeJS ReactJS $10m or $100/y https://egghead.io/pricing?dc=ng_socal Beginner Advanced
  • 42. pluralsight.com $29 month The most Angular courses Deep coverage of JS ...and .NET Beginner Advanced

Editor's Notes

  1. No API to learn for models! POJOS
  2. Use familiar markup