Date post: | 29-Nov-2014 |
Category: |
Presentations & Public Speaking |
Upload: | andy-bosch |
View: | 501 times |
Download: | 3 times |
Andy Bosch | www.jsf-academy.com
JSF und JavaScript
Ein paar Worte zu mir
• Name: Andy Bosch
• Freiberuflicher Architekt, Trainer, Entwickler, …
• Eigenes Trainingsprogramm zu JSF und Portlets
• JSF-Projekte seit 2004
Was habe ich heute vor?
• Relativ wenig JSF-Buzz(ok, ein bisschen schon)
• Vielmehr Fokus auf Architekturfragen und Software-Design, die sich mit JSF und JavaScript ergeben
JavaScript
• „The new kid on the block“
• Html5 Hype: Html, CSS, JavaScript
• Aber ganz ehrlich: Die Lösungen sind durchaus sehr abgefahren und fancy
Meine Meinung
• JavaScript hat seine Vorteile
• JSF hat seine Vorteile
� Durch eine gute Architektur und ein passendes Software-Design wird das Ganze aber auch erst richtig gut !!!
Schlechte Architektur
Grundsätzliches zu JSF
• Serverseitiges Framework !!!
• UI wird serverseitig generiert und Html an den Client ausgeliefert
• Klassisches Request/Response Paradigma
Grundsätzliches zu JavaScript
• Primär clientseitige Technologie
• Serverrequests i.d.R. über Ajax / REST-Calls
• Stark im Kommen: SPAs, die relativ „autark“ arbeiten
Und noch so ein Paradigma
• JSF ist hervorragend bei Kapselung: Html, CSS, JavaScript � alles versteckt
<p:calendar/>
Und noch so ein Paradigma
• Mit JavaScript dagegen ist es eher ein „Back to the roots“.
<div id="target">
Click here
</div>
$( "#target" ).click(function() {
alert( "Uuuuuups" );
});
Komplett gegensätzlich?
• JSF versucht, auch die Clientseite etwas zu unterstützen
• JSF hat ein wenig JavaScript Features
• JSF wird aber immer ein serverseitiges Framework bleiben!
Was kann JSF bzgl. JavaScript?
• Ajax-Integration
• Resource Handling
• Composite Components
• JavaScript Eventhandler
• PassThroughElements
• PrependId
JavaScript World
http://www.hanselman.com/blog/TheBigGlossaryOfOpenSourceJavaScriptA
ndWebFrameworksWithCoolNames.aspx
Was zeige ich nun?
• Integrationsszenarien
• Do‘s and Dont‘s
• Aber vor allem eins:Ein Architekturbild
Der Client wird mächtiger
UI-Layer
Service-Layer
Backend-Layer
JSF
CDI
JPA Hibernate
CDI
Browser
Server
jQuery BootstrapPresentation-Layer
Ich will Sourcecode sehen
• Ein erstes Beispiel mit JQuery
Szenario:
Feld auf enabled und disabled
Lessons Learned (1)
• Keinen State von Komponenten via JS ändern, ohne dass es JSF (Komponentenbaum) mitbekommt
• Der State in JSF ist ein enormer Vorteil, auch wenn es sich manchmal anders anfühlt ☺
Das Beispiel etwas genauer
• Einbindung von Resourcen
• Resource Relocation
<h:outputScript library="jquery"
name="jquery.js"/>
<h:outputScript library="jquery"
name="jquery.js“
target="head“ />
Resource Relocationunter der Lupe (1/2)
<h:head>
</h:head>
<h:body>
<pf:calendar />
<anotherCoolOne:greatSlider />
<stillMore:superCoolListbox />
</h:body>
Resource Relocationunter der Lupe (2/2)
<composite:implementation>
<h3>Some headline</h3>
<div>further html stuff … </div>
<h:outputScript library="jquery"
name="jquery-min.js"
target="head“ />
</composite:implementation>
jQuery Selectors
• Über NamingContainer
• Escaping in jQuery
• Oder mittels prependId
$( "#myform:myBtn" )
$( "#myform\\:myBtn" )
<h:form prependId="false" …>
$( "#myBtn" )
Tricky: Listboxen
• Ergänzung von Listboxen
Lessons Learned (2)
• Siehe Regel 1, betrifft im weitesten Sinne auch den Komponentenstate
• Achtung: Das soll keine Schikane sein, das ist Security (ok, der Übergang ist fliessend)
Weiterer Stolperstein:Form Submit
• Form Submit via JavaScript
Lessons Learned (3)
• Ein Form-Submit löst noch keinen Button-Klick aus
• Allerdings wird bei einem Form-Submit das Modell aktualisiert
• Lösung ggf. mit Button-Klick via JavaScript oder eigener Komponente
Und noch einer:Client- versus Server-Side
<h:inputText value="#{personBean.firstname}" />
...
$( "#myBtn" ).click(function() {
alert( "Du heisst: " +
"#{personBean.firstname}" +
" !" );
});
...
Einsatz von JS Frameworks
• Ok, die grundsätzlichen Dinge sind jetzt klar.
• Aber wie kombiniere ich JSF mit JS?
Wie binde ich überhaupt JS ein?JS Frameworks
• Heutzutage eigentlich kaum noch „manuelles JavaScript“
• Viele große, noch mehr kleine JS-Frameworks
• anguarJS, bootstrap, jQuery, uvm.
Bootstrap
• Im Fokus: Responsiveness
• Mobile First
• Ziel: Gestaltung / Design
• Html + Css Vorlagen, Grid-System
ShowCase
• Responsive Design am Beispiel
Bootstrap: CSS Design<div class="container">
<div class="row">
<div class="col-md-12">
Hier ist ein Spaltenelement
<a href=„nextPage.html“>Weiter</a>
</div>
</div>
</div>
...
Bootstrap: CSS Design<div class="container">
<div class="row">
<div class="col-md-12">
<a jsf:action="bootstrap-navi"
class="btn btn-primary"
id="myToolButton" href="#"
data-toggle="myTooltip"
title="this is text">
Back Button
</a>
</div>
...
PassThroughElemente
Bootstrap Komponenten
Beispiel Bootstrap: Html<ul class="nav nav-pills">
<li class="active">
<a href="#">Männlich</a>
</li>
<li>
<a href="#">Weiblich</a>
</li>
</ul>
Bootstrap mit Composites 1/3<composite:implementation>
<h:outputScript library="bootstrap"
name="jquery-1.8.2.js" target="head" />
<h:outputScript library="bootstrap"
name="bootstrap.js" target="head" />
<h:outputStylesheet library="bootstrap"
name="bootstrap.css" />
...
</composite:implementation>
Bootstrap mit Composites 2/3<ul class="nav nav-pills">
<li class="#{cc.attrs.gender=='m' ? 'active' : ''}">
<h:commandLink value="Männlich"
action="#{personBean.setMale}" />
</li>
<li class="#{cc.attrs.gender=='w' ? 'active' : ''}">
<h:commandLink value="Weiblich"
action="#{personBean.setFemale}" />
</li>
</ul>
Bootstrap mit Composites 3/3
<h:body>
Geschlecht:
<myc:gender gender="#{personBean.gender}"/>
</h:body>
Bootstrap: Zwischenfazit
• CSS Design / Grids ergänzen JSF optimal
• Eine Kapselung von Elementen mittels JSF Composites macht durchaus Sinn
• Meine Idee? Nein! Siehe BootsFaces!
Kapselung: BootsFaces<b:container>
<b:row>
<b:column>
<h1>Hello, world!</h1>
<b:alert severity="success">
<strong>Well done!</strong>
Great stuff
</b:alert>
</b:column>
</b:row>
</b:container>
...
angularJS
• Ziel: SPAs (Single Page Apps)
• MVVM (Model-View-Viewmodel)
Two-Way Data Binding<form ng-app="myApp">
Vorname:
<input id="myFirst" type="text" ng-model="first" />
Nachname:
<input id="myLast" type="text" ng-model="last" />
Somit heisst du: {{ first + ' ' + last }}
</form>
Geht auch mit JSF nativ<h:form>
Vorname:
<h:inputText id="myFirst" value="#{personBean.firstname}">
<f:ajax render="out" event="keyup"/>
</h:inputText>
Nachname:
<h:inputText id="myLast" value="#{personBean.lastname}">
<f:ajax render="out" event="keyup"/>
</h:inputText>
Somit heisst du:
<h:outputText id="out" value="#{personBean.firstname}
#{personBean.lastname}" />
</h:form>
JSF + angularJS
• SPAs mit einem mächtigen „UI-Backend“
• JSF Calls statt REST Calls
• Achtung Paradigma: Angular betreibt Manipulationen im DOM Tree, JSF (Server State) kommt damit nicht klar!
JSF + angularJS
• The one thing I like about JSF is it simple, declarative approach. But once you start to write an AJAX client, simplicity soon gets lost. The more Javascript code you add, the more you move away from the declarative approach to a more imperative approach. (Zitat aus BeyondJava.net)
Same procedure:AngularFaces
<pui:datatable value="carTableBean.carTable" var="row">
<pui:column header="Brand" sortable="true"
closable="true">{{row.brand}}</pui:column>
<pui:column header="Type">
{{row.type}}
</pui:column>
<pui:column header="Year" sortBy="toNumber(year)">
{{row.year}}
</pui:column>
<pui:column header="Color" sortable="true"
closable="true">{{row.color}}</pui:column>
</pui:datatable>
JSF I18N<html xmlns="http://www.w3.org/1999/xhtml"
ng-app="chatApplication"
dir="#{facesContext.viewRoot.locale.language
eq 'ar' ? 'rtl' : 'ltr' }">
...
<label class="chat-label">
#{i18n.welcomeMessage} {{user}}
</label>
Entnommen aus einem Blogpost von Ed Burns
Einschätzung
• Ist das jetzt genial?Oder doch etwas spooky?
UI Architektur Ansätze
• JavaScript + REST (ROCA-Style)
• JSF pure (full server centric)
• JSF + JavaScript (client-centric mit server-side State)
Layer-Modell
UI-Layer
Service-Layer
Backend-Layer
JSF
CDI
JPA Hibernate
CDI
Browser
Server
jQuery BootstrapPresentation-Layer
SSE? Server Push? WebSocket?
• Gehört irgendwie mit dazu zu dieser Fragestellung
• Ist eher eine zusätzliche Option als eine weitere Architekturvariante
• Integriert sich hervorragend: Session State + aktuelle Push-Infos
Fazit (1/2)
• JSF und JavaScript schließen sich nicht gegenseitig aus, sondern ergänzen sich!
• Es gibt ein paar Stolpersteine, die jedoch nicht allzu schwerwiegend sind.
Fazit (2/2)
• Den goldenen Schlüssel für ein Projekt-Setup gibt es nicht, daher braucht man ja auch (UI-) Architekten