Binding, BindingContext, BindingManager
For each UI component bound to a PMO property, linkki creates a so called
Binding. The methods of this
Binding ensure that subsequent changes in the PMO lead to an update of the UI component, and vice versa.
Bindings in linkki are part of a
BindingContext. Typically, a
BindingContext contains all
Bindings of a page or a section. Changes to a bound object (PMO or UI component) trigger an update of all
Bindings in the same context. A single
BindingContext can contain
Bindings linked to different PMOs.
BindingManager is used. The most important task of a
BindingManager is to provide validation across all managed
BindingContexts, as input changes in one
BindingContext may lead to validation problems in others. For that, a ValidationService is invoked upon changes in any of the managed
BindingContexts. The result is then propagated to the other
BindingContexts for display.
In addition to the validation,
BindingManager also provides methods to create
BindingContexts with default values that apply to all managed
BindingContext can either be created using only a name that is used as an identifier, or additionally with a
PropertyBehaviorProvider that defines a specific set of behaviors. A
Class can also be passed as an alternative to be used a identifier.
The scope of UI updates
BindingContext ensures that all contained
Bindings are updated if one of them changes. The
Bindings in turn update their respective UI fields. Thus, a
BindingContext defines the "scope" of UI updates for its fields.
It is common practice to use a
BindingContext for all fields visible to the user at a time. For example a single
BindingContext for a big form. On the other hand, if there are multiple tab sheets it’s best to use a separate
BindingContext for each of them, as only one of the tabs is visible at a time. This avoids unnecessary updates of fields that aren’t even visible.
BindingManager is responsible for everything that is beyond that aspect of currently visible fields. For example the input of data on one tab sheet may result in a validation violation on another tab sheet. Hence validation is part of the
If UI components depend on information inside a different
UiUpdateObserver can be used to ensure updates are triggered when the referenced content changes. The
UiUpdateObserver is attached to a
BindingManager, which calls the
uiUpdated() method each time a UI update occurs (e.g. when a
BindingContext belonging to the
BindingManager updates). Since the class
UiUpdateObserver, it can be directly added as such. Using this mechanism, UI created by linkki would be updated with every change inside the same
A possible use case might look like this: A
TabSheetArea consists of several tab sheets with each using its own, separate
BindingContext. This ensures that a change to the currently visible tab is propagated to other fields inside the same tab, while not affecting non-visible fields contained in different tabs to improve performance. These updates can freely be skipped, since a tab sheet’s
BindingContext always receives an update when the tab is selected and becomes visible.
Adding a permanently visible summary section (referencing data from multiple tab sheets) to the page would require an update whenever a change is made to an arbitrary
BindingContext. Otherwise, it would display outdated data since changes of referenced data are not propagated. This can be achieved by adding the new section’s
BindingContext as a
UiUpdateObserver to the
BindingManager of the page.
BindingContext summarySectionBindingContext = bindingManager.getContext("summarySection"); bindingManager.addUiUpdateObserver(summarySectionBindingContext); // ... create summary section with this binding context
Executing additional action after model update
Sometimes it is necessary to execute an action before each UI update that is triggered by a model change. This can be achieved by using the so called
afterModelChangedHandler when creating a
BindingContext. If this handler is set upon creation, it is called whenever a value is pushed to the model in a
BindingContext before the UI is updated.
Updating the UI explicitly
Sometimes, it is necessary to trigger an UI explicitly. The class
BindingContext provides two methods to achieve that:
This method should be called by actions out of the
BindingContextthat result in a model change. The
BindingContextwill then update the
Bindingsas if a change happened inside of the
Example: Assuming the value of a field would be changed by a dialog that is in a different
BindingContext. In that case, confirming the dialog should result in calling the method
This method should be called by actions that do not change the model, but triggers an update of the UI.
Example: When a tab sheet is switched to visible, the content needs to be updated to reflect the model. But no model changes are made by this action.