angular beans

41
If AngularJS is what should have been HTML, if CDI is what should have been JavaEE, AngularBeans is what should be JSF!

Upload: bessem-hmidi

Post on 09-Aug-2015

1.194 views

Category:

Technology


0 download

TRANSCRIPT

If AngularJS is what should have been HTML, if CDI is what should have been JavaEE,

AngularBeans is what should be JSF!

Agenda

• “web applications”, new needs (frameworks view)

• AngularBeans

• Q&A

“web applications”, new needs

Single page web application (SPA)& Thin server conceptReal-time & fall back Json & JsonRPC

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

……

RT –WebAPP : WebSockets

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

JS frameworkMVC/MVVM/MV*2 Ways DataBindingModulesServicesControllersEvents

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

JavaEE7 (+)

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

AngularBeans : my first bean (style 1) : result

@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 (adding log)

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

http://bessemhmidi.github.io/AngularBeans/

THANK YOU!