Date post: | 15-Jan-2015 |
Category: |
Technology |
Upload: | gunnar-hillert |
View: | 1,411 times |
Download: | 2 times |
CREATING MODULAR TEST DRIVEN SPAS WITH SPRING ANDANGULAR JS
Created by / Gunnar Hillert @ghillert
GOALSAngularJS OverviewBuild and DeploymentIntegration with SpringTestingModularizationUI Considerations
ME(Java) Web developer since 2005Struts 1+2, Spring MVC, GWT, FlexSpring Integration + XD committerAngularJS since Jan 2014
AUDIENCE - WHAT DO YOU USE?AngularJS? 50%Backbone? 20%JQuery? 90%Are you using any other SPA Framework? ExtJSSpring MVC? 60%Spring Boot? 10%
WHAT ARE SPAS?A single-page application (SPA), also known assingle-page interface (SPI), is a web application
or web site that fits on a single web page with thegoal of providing a more fluid user experience
akin to a desktop application.
Wikipedia
WHAT ARE SPAS?
JAVASCRIPT WTF 1/2http://wtfjs.com/
parseInt('crap'); // NaNparseInt('crap', 16); // 12
NaN
12
JAVASCRIPT WTF 2/2http://wtfjs.com/
(2 + "3"); // 23(2 + +"3"); // 5(+""); // 0
23
5
0
FROM BACKBONE TO ANGULARToo many moving parts, choices
Boilerplate Code
Marionette, Backbone.ModelBinder, Backbone.Relational
ANGULAR JS BASICSModel
View (Templates)
Controller
Expressions
Directives
Modules
See also: AngularJS Concepts
¡HOLA!<div ng-app ng-init="firstName='Angular';lastName='rocks'"> <div> First Name: <input type="text" ng-model="firstName"> </div> <div> Last Name: <input type="text" ng-model="lastName"> </div> <div> <b>Complete Name:</b> {{firstName + ' ' + lastName | uppercase}} </div></div>
Demo
MODEL 1/2Angular is very flexible about your model
Ultimately expressed via the $scope
$scope = Glue between Controller and View
$scope mimics DOM (Hierarchical, one $rootScope)
$watch, $apply
MODEL 2/2Killer Feature: Data-Binding
Model === single-source-of-truth
View reflects model changes automatically
VIEWHTML is your templating Engine
Minimize logic as much as possible
Consider Custom Directives
CONTROLLERUsed to "setup" your $scope
Add behavior to your $scope
Don't do UI work using controllers!!
Use directives and filters instead
¡HOLA! V2.0 - VIEW<div ng-app="hola" ng-controller="NameController"> <div> First Name: <input type="text" ng-model="firstName"> </div> <div> Last Name: <input type="text" ng-model="lastName"> </div> <div> <b>Complete Name:</b> {{firstName + ' ' + lastName | uppercase}} </div></div>
Demo
¡HOLA! V2.0 - CONTROLLER<script>
</script>
(function(){ var app = angular.module('hola', []); app.controller('NameController', function($scope){ $scope.firstName='Angular'; $scope.lastName='rocks'; }); })();
Demo
app.controller('NameCtrl', function($scope){ ... });app.controller('NameCtrl', ['$scope', function($scope){ ... }]);
DEPENDENCY INJECTIONConsider using array notation
Or use ngmin
grunt-ngmin, gulp-ngmin
EXPRESSIONS{{ expression }}
No Control Flow Statements
Can use filters inside expressions:
{{ 'abcd' | uppercase }}
DIRECTIVESAre markers on a DOM element
Attach behavior/transform DOM elements
ng-controller, ng-app ...
TYPES OF DIRECTIVESAttribute (default)
Element
Class
See: https://gist.github.com/CMCDragonkai/6282750
MODULESBear with me ...
BUILD AND DEPLOYMENT
STRATEGIES - JAVA TOOLING
Spring 4.1 (SPR-10310, SPR-10933)See
Wro4jJawr
Blog PostWebJars
STRATEGIES - JAVASCRIPT TOOLINGNode (Npm)Grunt (Gulp)BowerYeoman (angular-seed)
MAKE MAVEN AND GRADLE GRUNTPlugins exist for Gradle and MavenSpring XD uses Gradle integrationbotanic-ng uses Maven integrationSpring Boot plus Maven Frontend Plugin
INTEGRATION WITHSPRING (BOOT)
HELLO WORLD FITS INTO TWEET@Controllerclass ThisWillActuallyRun { @RequestMapping("/") @ResponseBody String home() { "Hello World!" }}
RAPID PROTOTYPINGSpring Scripts ( )Starter POMsÜber-Jars support (can create WARs also)Maven + Gradle PluginsAutoConfiguration support
Samples
MAIN IS BACK@EnableAutoConfiguration @ComponentScan @EnableSchedulingpublic class MainApp extends RepositoryRestMvcConfiguration { @Override protected void configureRepositoryRestConfiguration( RepositoryRestConfiguration config) { config.exposeIdsFor(Image. class, Garden.class, Plant.class); config.setBaseUri(URI.create("/api")); } public static void main(String[] args) { final ConfigurableApplicationContext context = SpringApplication.run(MainApp. class, args); ... } @Bean MultipartConfigElement multipartConfigElement() { ... } ...}
SERVING STATIC CONTENT/META-INF/resources/
/resources/
/static/
/public/
Also supports WebJars
MAKE BOOT MODULES (UI) PLUGGABLE
DEMO BACKEND
MODULARIZATION
ANGULARJS MODULEShttps://docs.angularjs.org/guide/module
Compartmentalize sections of your application
Does not deal with script loading
angular.module('myModule', []). config(function(injectables) { // provider-injector // This is an example of config block. }). run(function(injectables) { // instance-injector // Like a Main method });
MODULARIZATION FUTUREECMAScript 6 modules
is being written in ES6AngularJS 2
Web Components
MORE COOLNESS
FILTERS...<tr ng-repeat= "item in jobDefinitions | filter:filterQuery | orderBy:'name'">...
FILE UPLOADangular-file-upload (nervgh)
angular-file-upload (danialfarid)
File Reader
Traditional Post
ROUTINGngRoute (built-in)
Routing on steroids using ui-router
ROUTING USING UI-ROUTERstate machine
nested views
Spring XD's routes.js
TESTINGE2E testing with Protractor
Unit Testing using and Karma Jasmine
UI CONSIDERATIONSBootstrap
Keep your CSS maintainable with and Less Sass
RESOURCES
THANK YOU!!Source Code + Preso:
https://github.com/ghillert/botanic-ng