Sunday, November 7, 2010

Scala exercise 6: Tackling the Wicket hierarchy mismatch problem

Introduction


This is the sixth exercise in my Scala exercises series. If you haven’t seen it before, you may want to start from the previous exercises. Below is exercise 6: Tackling the Wicket hierarchy mismatch problem.
Some people have alleged that a weakness in Wicket is that you have to keep the hierarchy of the component tree in sync with that of the HTML elements. For example, for the HTML code:

<html>
<form wicket:id="f">
<input type="text" wicket:id="num">
<input type="submit" value="OK">
</form>
<span wicket:id="result">10</span>
</html>

You would construct a component tree (in Scala) like:

class MyPage extends WebPage {
val f = new Form[MyPage]("f") {
override def onSubmit() {
...
}
}
add(f) //add the form to the page
val numField = new TextField[Int]("num")
f.add(numField) //add the text field to the form
val r = new Label("result")
add(r) //add the label to the page
}

The problem is that, if, say, you'd like to move the result span into the form, you must change the code accordingly:

class MyPage extends WebPage {
...
val r = new Label("result")
f.add(r) //you must add the label to the form, not to the page!
}

and a common problem is that we may forget to do so. While there is no easy way to solve this problem, you could make the Scala code reflect the HTML structure visually (and look more like a declarative UI):

class MyPage extends WebPage {
//the "ctx" represents a surrounding container context for the
//construction of child components
this containing { ctx =>
val f = ...
ctx.add(f) //add the form to the context (the page)
f containing { ctx =>
val numField = ...
ctx.add(numField) //add the text field to the context (the form)
}
val r = new Label("result")
ctx.add(r) //add the label to the context (the page)
}
}

Note that the Scala code reflects the structure of the HTML code so you can compare them visually. In addition, if you need to move the label into the form, you can simply cut and paste the construction code of the label into that context of the form:

class MyPage extends WebPage {
//the "ctx" represents a surrounding container context for the
this containing { ctx =>
val f = ...
ctx.add(f)
f containing { ctx =>
val numField = ...
ctx.add(numField)
//the following lines were simply cut and pasted into here
val r = new Label("result")
ctx.add(r)
}
}
}

Now, your task is to implement this solution by creating the necessary code. Try to do it now.
See the answer here.


2 comments:

  1. You know, four weeks ago I came up with an idea of a domain specific language that would make component hierarchy source codes visually nice. Pretty much the same idea as this (except this is implemented with a complete programming language instead of a DSL). It took me a whole week before I realized that the benefits would not make up for the facts that IDE's code completion and compiler errors are lost. Now I found out that hierarchial code structuring is possible in Scala and I think it's great! It's also typical that I find out about this later rather than sooner :) I wish we could start using Scala in the company I work for but I don't see it happening in the next few years.

    ReplyDelete
  2. Glad that you find this information useful! It is indeed a strength of Scala that you can create DSLs with IDE auto-completion and static type checking! You may advocate these benefits to your boss and maybe he will allow you to work on a small project as a pilot? If you don't try, you will never know.

    ReplyDelete