Soft binding versus hard binding
DomUI data binding uses a form of data binding we call "soft binding". When you bind some model property to a component it is the component which maintains (remembers) the binding. The actual binding of the data is triggered by two global events:
- When a request enters the servers we move data from control to model
- When all user logic has finished, and the response is to be rendered back we move data from model to control. This means the control will show the value from the model when rendered back in the browser.
Because the binding itself is maintained by the control bindings are only active while the control itself is attached to a page. If a control gets removed from a page it's bindings will not update. But as soon as a control is added to a page (again) binding will be updated.
The alternative to "soft binding" is "hard binding". In hard binding all property setters of classes are coded in such a way that they call listeners as soon as a setXxx() call changes the value of the property. Instrumenting all setters to do this properly adds yet more boilerplate to Java's already very verbose "properties" which is a disadvantage. In addition having setters propagate changes means that it is very hard to control when bindings execute. And finally, since objects might live quite a while it becomes important to be able to clean up listeners on properties, or the system leaks memory or CPU cycles.
Using soft binding prevents all this: the update mechanism is bound to the request/response cycle, and bindings are automatically removed as soon as components go out of scope.
How components register bindings
Binding error handling
Why is binding order important?
Components on the screen are ordered naturally, by their DOM location as created by the developer. But to handle binding properly it is important that binding is done in proper order.
Let's give an example. We have a screen with two combo boxes:
The "Country" combo contains a few countries, the "City" combo contains cities in all of these countries - not just of the selected country.
Now let's see what happens if we order binding in "dom order"... Say the user changes "Netherlands" to "Great Britain":
- The request enters the server, and binding executes moveControlToModel.
- "Country" changed to "Great Britain":
- The model discovers that city "Amsterdam" is not in Great Britain, so it changes the "city" property to "London".
- But now we bind "city" which is "Amsterdam" from the UI code.
- The binder overwrites "London" with "Amsterdam", and updates "Country" back to Netherlands.
Clearly this is not really what we want. We need to have some "order" imposed on the bindings, so that it behaves as expected.
How DomUI orders binding
When a request comes in the binder (SimpleBinder) will run moveControlToModel, after all components have obtained their value(s) from the request. It does that as follows:
- Walk the tree, and find all bindings.
- Check each binding for a changed value, i.e. where the model value differs from the control value.
- For items that have the same value: ignore
- We now have a list of bindings whose value changed. Order these bindings as follows:
- A "deeper" binding comes before a "higher" binding
- Bindings at the same "level" execute in order of dom traversal.
- Now bind all values as per the above ordering.
By ordering like this most binding issues should resolve themselves automatically.