vaadin+scala
DESCRIPTION
Slides of the talk by Oleg Aleshko on Vaadin and Scala at scalaby#10TRANSCRIPT
Vaadin+Scala
- Simple programming model- Secure- No javascript- Beautiful
Why?
Simple programming model
- Abstracted from HTTP- No request/response/session mess- All AJAX- Just a web page
Secure
- All server-side- Validations- No code on client- CSRF, XSS protection built-in
No javascript
- No bad parts- Good parts still accessible- Built on GWT- Large test suite for each browser
Beautiful
- Mature codebase- Thinking of U and I- Widgets and addons- Themes
Performance
- Almost every event is handled on server- Optimized wire format- No page reload- Static content
Performance vs PrimeFaces
Scalability Study - QuickTickets
+Scala
mandatory ugly java slide
6 class TransactionPage(controller:TransactionController=new TransactionController) extends BasePage { 7 model.params = params 8 compositionRoot = new VerticalLayout { 9 val form = new Form { 10 caption = 'hello 11 val beanItem = new BeanItem(model) { 12 item = this 13 visibleItemProperties = propertyIds().filter(_ != "progress") 14 } 15 field("price").foreach { p => 16 p.required = true 17 p.validators += >=(10.0) 18 } 19 } 20 components ++= 21 Button('check, Notification.show(model.toString)) :: 22 Button('start, validated(form)(controller.start(done))) :: 23 form :: 24 new ProgressIndicator {property = form.beanItem.property("progress")} :: 25 Nil 26 } 27 def done = Notification.show('done, Type.Tray) 28 def model = controller.model 29 }
+Scala
- wraps Vaadin api into idiomatic Scala- closures, Options, etc.
+Scaladin
+Scala => declarative
- comparable to JSON1 {"transactionPage": { 2 "controller": "TransactionController", 3 "compositionRoot": { 4 "type": "VerticalLayout", 5 "components": [ 6 { 7 "type": "Button", 8 "caption": "hello"
.... 9 } 10 ] 11 } 12 }}
- no need to reference view from controller- statically checked- support for HTML templates
+Scala => inline constructorsclass TransactionPage(controller: TransactionController = new TransactionController) extends BasePage {
//body goes here
}
+Scala => DelayedInit
8 trait BasePage extends CustomComponent with Validations with DelayedInit { 9 var params: String = "" ...
16 def init(params: String) = {
17 this.params = params 18 initCode.foreach(_()) 19 } 20 }
14 case class TabView(name: String)(content: => Seq[Component] = stubContent(name)) 15 extends VerticalLayout with View { 16 def enter(event: ViewChangeEvent) { 17 //showing that state persists and lazy loading is possible 18 val params = event.getParameters 19 content.collect {
20 case page: BasePage => add(page).init(params) 21 case view => add(view) 22 } 23 Notification.show("Entered " + name + " with params " + params) 24 } 25 }
class TransactionPage(controller: TransactionController = new TransactionController) extends BasePage {
model.params = this.params
+Scala => callbacks and HOFsButton('start, validated(form)(controller.start(done)))
def apply(caption: String, clickListener: => Unit): Button
def validated(form: Form)(action: => Unit)
def start(done: => Unit)
- increase code reuse- decrease coupling
+Scala => symbols
- localization- natural namescaption = 'hello
implicit def translateSymbol(s: Symbol) = s"${s.name} locale:${self.locale}"
implicit def translateTuple[T](s: (Symbol, T)) (implicit toParams: T => TranslationParams) = translateSymbol(s._1).format(toParams(s._2).p: _*)
validators += >=(10.0)
def >=[T](bound: T)(implicit ord: Ordering[T]): Option[Any] => Validation = { import ord._; v => v match { case Some(v: T) if v >= bound => Valid case _ => Invalid(Symbol("should be greater %s") -> bound :: Nil) } }
+Scala => structural types
- navigate in nested objectsval form = new Form { val beanItem = new BeanItem(model) {
...
form.beanItem.property("progress")
- eliminate dependenciestrait Translation {self: {def locale: Option[Locale]} =>
+JRebel
- Reloading classes as if they were templates- Free for Scala- Free for Vaadin Pro users
Thank you!Q&A