angular beans
TRANSCRIPT
If AngularJS is what should have been HTML, if CDI is what should have been JavaEE,
AngularBeans is what should be JSF!
Client Server
Initial Req
GET,POST…
Classic approach
HTML Rendrering
Page reloadingSometes req resource (via
ajax )
Service Backend
HTML Generation
UI logicMVC
Validations…Sessions care
Client Server
Initial Req
GET,POST…
SPA approach
HTML Rendrering
Page reloading
HTML Rendrering
Data updates
UI logic
Validation
Session data
Simulated naviguation
(via #)
Thin Server
Backend
RestJsonRPCWsocketComet
……
SocketIO /SockJS:
• Abstracts WebSocket communications to automatically fall back to flash streaming or long-polling when necessary (on either server or client)
• Adds features like heartbeats, timeouts, and disconnection support not provided in WebSocket API
JSON/JSON RPC
{{
"is": ["compact", "readable"] "web_service": "JS native object" "enough" : "for majority of needs"
}}
REST (Representational State Transfer)
Restfull HTTP / Restfull ArchitecturesHTTP Methods (GET/POST/DELETE…) as CRUDBookMarking Stateless By Design scalability+
JSF
JSF 1.0 (March 2004) initial releaseJSF 1.1 (May 2004) bugfix release.JSF 1.2 (May 2006) sarting to be serious!
JSF 2.0 (June 2009) second major release:100%Facelets / HTML support (passthrow…)@ViewScoped (ajax aware)
JSF /But
JSF 1.0 (March 2004) :@that time JS just used for animationsNo JIT (performance)No Ajax/yetNo HTML5No Restfull HTTP/ArchitectureNo SPA & Thin server concept
Life cycle -> good extentions points but
give us a more complex and errors-prone
framework Scalability (-)
HTML5 (-) even with passthrow.
Facelets -> xhtmlServer Side validation(-)
bookMarking (-)Server Side UI-Logic (-)
Performances
What we need ?
Single framework that care about:SPA & Thin Server conceptsPure HTML5 support (not a sever side generated HTML5) we can use tools as bower, grunt, yeoman generators…Real Time support + fall back when needed“clear and cleans” url’s
AngularBeans
AngularJS JavaEE (CDI) BackendJson RPCBean ValidationURL Based File UploadCDI Bean Angular ServicesCDI EventsAngular EventReal Time @RealTime & BroadcastingSystemModelQuery (server->client)SockJs auto detection and Native support!
AngularBeans : Requirements
JDK 7 (or+)JavaEE7 (or+) Web profile or full profile AS.AngularJS lib--------------------
First production-ready release:
1.0.1 sept 2015
AngularBeans: principle
@AngularBean 1
@AngularBean 2
NG Service 1
NG Service 2
NG ctrl
NG ctrl
NG ctrl
@ Other CDI Bean
« Singleton »
« Singleton »
Dependency injectionDependency
injection
AngularBeans CDI scopes :
@RequestScoped@ApplicationScoped@NGSesionScoped :
classic @SessionScoped is bound only to the classic HTTP session or the websocket session but only one will be active we cannot open a conversation with the same CDI bean that include a http Get request and after that a websocket call for example.
But with @NGSessionScoped shared context between websocket calls and classic http methods calls.
we can have many websockets sessions (if many browser tabs open for example ) + 1 http session all grouped in a single NG Session)
AngularBeans : HTML head & fallback feature
Angulars beans will auto detect that and will use a sockJS server end point to exploit sockJS features/
else it will use a JSR356 raw Websocket for real time interactions (no fall back feature then)
angular-beans.js will be generated dynamically
AngularBeans : my first bean (style 1)
@AngularBean@RequestScopedpublic class CalcBean {
private int a, b;private int result;
@NGModelpublic int getA() {return a;}
@NGModelpublic int getB() {return b;}@NGModelpublic int getResult() {return result;}
@GET@NGSubmit(backEndModels = { "a", "b" })@NGReturn(model = "result")public int add() {result = a + b;return result;
}
public void setA(int a) {this.a = a;}
public void setB(int b) {this.b = b;}}
Get method (can be @Post, @Put, @Delete or @RealTime
If any: dfault->: @Get
Array of the server side models to be synchronused with the js proxy state, if
«*» all properties marqued @Model will be updated (before method call ofc)
Front ent Model to be synchronied with the return of the method
Additional attribute ->,updates=« » : array of other front end
models to be updated too
<!DOCTYPE html><html><head>
<script type="text/javascript"src="bower_components/angularjs/angular.js"></script>
<script type="text/javascript" src="angular-beans.js"></script>
<script type="text/javascript">var myApp = angular.module("myApp", [ "angularBeans" ]);myApp.controller('calcCtrl', function($scope, calcBean) {$scope.clacBean = calcBean;});</script>
</head>
AngularBeans : my first bean (style 1) :HTML
module generated by AngularBeans
CalcBean is now an injectable service
<body ng-app="myApp"><div ng-controller="calcCtrl">
<label>a:</label> <input type="text" ng-model="clacBean.a"> <label>b:</label><input type="text" ng-model="clacBean.b">
<button ng-click="clacBean.add()">send</button><br />
<h2>Result: {{clacBean.result}}</h2></div></body>
</html>
AngularBeans : my first bean (style 1) :HTML
Diect bean call
@AngularBean@RequestScopedpublic class CalcBean {
@GETpublic int add(int a, int b){return a + b;}
}
AngularBeans : my first bean (style 2)
Args passed via RPC style (can be primitves, objects, arrays or var args)
AngularBeans : my first bean (style 2) :HTML
<script type="text/javascript">var myApp = angular.module("myApp", [ "angularBeans" ]);
myApp.controller('calcCtrl', function($scope, calcBean) {
$scope.add = function(a,b) {calcBean.add(a,b).then(function(data){$scope.result=data;});}
});</script>
AngularBeans : my first bean (style 2) :HTML
<body ng-app="myApp"><div ng-controller="calcCtrl">
<label>a:</label> <input type="text" ng-model="a"> <label>b:</label><input type="text" ng-model="b">
<button ng-click="add(a,b)">send</button><br />
<h2>Result: {{result}}</h2></div></body>
AngularBeans : my first bean (with binding) :HTML
<script type="text/javascript">var myApp = angular.module("myApp", [ "angularBeans" ]);
myApp.controller('calcCtrl', function($scope, calcBean) {
angularBeans.bind($scope,calcBean,["result"]);});</script> Scope will be auto synchronized with the bean proxy (the
service) state, this function take as argument an array of the properties to be bound, in this case « result » is the
main return so we must add @NGReturn(model="result") on the add() method of the bean
AngularBeans : my first bean (adding log)import angularBeans.log.NGLogger;import angularBeans.log.NGLogger.Level;
@AngularBean@RequestScopedpublic class CalcBean {
@InjectNGLogger logger;
@GET@NGReturn(model = "result")public int add(int a, int b) {
logger.log(Level.WARN, "a=%s , b=%s , a+b= %s", a, b, a + b);
return a + b;}}
AngularBeans : my first bean (@NGPostconstruct)
@InjectNGLogger logger;
@NGPostConstructpublic void init(){logger.log(Level.INFO, "this method will be called at the service creation");}
AngularBeans : my first bean (ModelQuey)
package org.angularbeans.example;
public class Message {
private String summary;private String detail;
public Message(String summary, String detail) {super();this.summary = summary;this.detail = detail;}}
AngularBeans : my first bean (ModelQuey)
@AngularBean@RequestScopedpublic class CalcBean {
@InjectNGLogger logger;
@InjectModelQuery modelQuery;
@NGPostConstructpublic void init() {logger.log(Level.INFO,"this method will be called at the service creation");}
@GET@NGReturn(model = "result")public int add(int a, int b) {
logger.log(Level.WARN, "a=%s , b=%s , a+b= %s", a, b, a + b);
modelQuery.pushTo("messages",new Message("attention", "calculation...")).setProperty("time",new Date());;return a + b;}}
AngularBeans : my first bean (ModelQuey) :HTML
myApp.controller('calcCtrl', function($scope, calcBean) {
angularBeans.bind($scope,calcBean,["result","messages","time"]);});
<h2>Result: {{result}}</h2>
<ul ng-repeat="m in messages"><li>{{m.summary}} - {{m.detail}}</li></ul>
{{time}}
AngularBeans : my first bean (ModelQuey)
ModelQuery’s are simply a query’s from back end to front end to update their models
AngularBeans : my first bean real time & events
@InjectRealTimeClient client;
@RealTimepublic void notifyOthers(){
RealTimeMessage rtMessage=new RealTimeMessage().set("notification", "someData");
client.broadcast("calculationEvent",rtMessage, false);
}
This method will be called via websocket (or fall back strategy)
Broadcast the message to all connected sessions (can also
broadcast a QueryModel)
If false the sender will also receive the event
myApp.controller('calcCtrl', function($scope, calcBean) {
angularBeans.bind($scope,calcBean,["result","messages","time"]);
$scope.$on("calculationEvent",function(event,data){ alert(data.notification); });
});
AngularBeans : my first bean real time & events
AngularBeans : others examples
Form validation : https://gist.github.com/bessemHmidi/408438a2eae524f0348f
Files upload & LobWrapper (binary data like images):https://gist.github.com/bessemHmidi/5d13d62169236bc17a32