< PreviousChapter 6: Solution160knowledge about the Controller Component, in MVC/CT it is not allowed to bind DOM events directly onto controller actions. Instead, Event Values have to be changed, and the Presentation Actioning in the Controller then can react in sequence on those instead. This is required for pattern symme-try, Separation of Concerns and to let the Presentation Logic kick-in before the Presentation Actioning. ■Presentation Logic (PL): The active Presentation Logic aspect performs logical decisions, based on State Values, Data Values and Event Values. For HTML5 SPAs this can be, for instance, the decision whether a “login” button is enabled, based on the state and values of “username” and “password” input fields. ■Parameter Values (PV): The passive Parameter Values aspect provides a data structure consisting of general UI Fragment parameters. For HTML5 SPAs this can be, for instance, the position in the grid of a dashboard. In general UI Fragment parameters are values which are static values or val-ues which potentially do not change during the lifetime of a Component at all. ■Command Values (CV): The passive Command Values aspect provides a data structure consisting of one-time commands. For HTML5 SPAs this can be, for instance, the command “reset” or “resize.” Notice that these are usu-ally one-time information which auto-reset after all observers got notified. ■State Values (SV): The passive State Values aspect provides a data structure consisting of UI Fragment states. For HTML5 SPAs this can be, for instance, the information about list selection, field activation or field error. ■Data Values (DV): The passive Data Values aspect provides a data structure consisting of UI Fragment domain values. For HTML5 SPAs this can be, for instance, the domain values derived from the Business Model. ■Event Values (EV): The passive Event Values aspect provides a data struc-ture consisting of logical and domain-specifically abstracted UI Fragment interaction events of the user. For HTML5 SPAs this can be, for instance, the values indicating the domain-specific events triggered by a button click or list item selection. Different technical interaction events (like keyboard, mouse or touch gesture) usually map to the same logical Event Values. No-tice also that Event Values are usually one-time information which auto-reset after all observers got notified. ■Presentation Provisioning (PP): The active Presentation Provisioning aspect manages the provisioning of the Presentation Model with values from the Business Model. For HTML5 SPAs this can be, for instance, the fetching of business information via GraphQL. ■Presentation Actioning (PA): The active Presentation Actioning aspect re-acts to Presentation Model changes and performs actions towards the Hierarchical Dialog Architecture: Model-View-Controller/Component-Tree (MVC/CT)161Business Logic and its Business Model. For HTML5 SPAs this can be, for instance, the triggering of GraphQL data mutations and domain-specific functions. ■Business Model (BM): The passive Business Model aspect exists just for il-lustration purposes and represents the data structure of the Back End in the Front End. ■Business Logic (BL): The active Business Logic aspect exists just for illustra-tion purposes and represents the business services of the Back End in the Front End.6.8.9 MVC/CT Step 4: Presentation ProvisioningIn the fourth step, we add the necessary communication between Component As-pects for provisioning the Presentation Model (see Figure 6.24 on page 161). Ini-tially, the Component System triggers the execution of the Presentation Provisioning aspect of the Controller Component.This aspect then usually explicitly calls the Business Logic in order to get certain data from the Business Model. Alternatively, the Presentation Provisioning can observe the Business Logic for changes and this way re-act upon those changes implicitly.In both situations, the Presentation Provisioning aggregates, splits and trans-forms the data from the Business Model to fit the structure in the Presentation Model. It usually takes configuration data and writes it to the Parameter Values, and it takes Business Logic events to write Command Values. It also initializes State Values and writes domain data from the Business Model to the Data Values.While the Business Model is structured according to the domain, the Presenta-tion Model is structured according to the require-ments of the UI Fragment presentation.ParameterValuesStateValuesDataValuesBusinessModelBusinessLogicEventValuesPresentationProvisioningPresentationActioningModelControllerServicePresentationModelPresentationControlBusinessServiceSVDVEVPPPABMBLBSPCPMObservableCommandValuesPVCVFigure 6.24: MVC/CT Step 4: Presentation ProvisioningChapter 6: Solution162Notice the important existence of the Presentation Model layer in addition to the Business Model aspect. While the Business Model is structured according to the domain and contains just the bare domain data, the Presentation Model is struc-tured according to the abstraction of the User Interface Fragment and contains ad-ditional information (like states and events) which are not existing (and definitely should not exist) in the Business Model.6.8.10 MVC/CT Step 5: View Mask Data BindingIn the fifth step, we add the data binding between the Presentation Mod-el layer and the View Mask Layer (see Figure 6.25 on page 162).The Mask Rendering aspect takes Parameter Values (and optionally also Command Values) as its input and unidirectional updates the View Mask. The Command Binding takes Command Values as its input and unidirectional updates the View Mask. The State Binding takes State Val-ues as its input and unidirectional updates the View Mask. The Data Binding takes Data Values as its input and output and bidirectionally updates with the View Mask. Finally, the Event Binding takes the View Mask as its input and unidirectional up-dates the Event Values. All those data binding updates are triggered by Observers, both in the Presen-tation Model (provided by the Component System) and the View Mask (provided by the DOM). For more details on the Data Binding mechanism see Section 6.9 on page 164.Data Binding a View Mask is one of the most popu-lar mechanisms nowa-days in UI programming, as it greatly reduces the amount of required sche-matic code.View MaskParameterValuesStateValuesDataValuesCommandBindingDataBindingEventBindingStateBindingEventValuesViewModelObservableObservableObservableObservableSBViewMaskViewBindingPresentationLogicPresentationModelDBEBVMPLSVDVEVPMPLVBVMObservableCommandValuesObservablePVMaskRenderingCBCVMRObservableFigure 6.25: MVC/CT Step 5: Data BindingHierarchical Dialog Architecture: Model-View-Controller/Component-Tree (MVC/CT)1636.8.11 MVC/CT Step 6: Presentation LogicIn the sixth step, we add the important Presentation Logic communication to the Model Component (see Figure 6.26 on page 163). This aspect observes and reads Command, State, Data and Event Values, makes logical decisions based entirely on this information and writes back State and Data Values.Notice two things here: first, as in MVC/CT the Model Component has no knowledge either about the View nor the Controller Component, it is not allowed that the Model Component accesses information on them. The only input for deci-sion making is the own Presentation Model layer and external environmental infor-mation. Second, for the same reason, it is only allowed for the Presentation Logic to write back State and Data Values. Any direct actioning is not allowed.Finally, notice that Presentation Logic is really part of the Model Com-ponent, because it cannot be part of the View Component or “headless” testing a User Interface (where View Components are disabled) would be not possible. Morever, it cannot be part of the Controller Component or the presentation logic of reusable Widgets would have to be duplicated into the using Controller Components.6.8.12 MVC/CT Step 7: Presentation ActioningIn the seventh and last step, we add the Presentation Actioning communication to the Controller Component (see Figure 6.27 on page 164). The Presentation Ac-tioning aspect in the Controller Component reacts on State, Data and Event Values of the Presentation Model. For State and Data Values, it reads the actual values, for Event Values just the fact that the Event Value was “touched” is required.As a result, the Presentation Actioning aspect can update State Values, trigger the Presentation Provisioning or call the Business Logic in order to update data in the Business Model.Although perhaps not intuitive at the first spot, the Presentation Logic has to be part of the Model Component and neither the View nor Con-troller Components.ParameterValuesStateValuesDataValuesPresentationLogicEventValuesModelObservableObservableObservableObservableObservableObservablePresentationLogicPresentationModelPLSVDVEVPMPLCommandValuesObservablePVCVObservableFigure 6.26: MVC/CT Step 6: Presentation LogicChapter 6: Solution1646.9 Data Binding of Presentation ModelA bad design with a good presentation is doomed eventually. A good design with a bad presentation is doomed immediately. — Akin’s Laws of Spacecraft DesignThe Data Binding between the Presentation Model and the View Mask is important for MVC/CT and hence demands separate consideration. First, we describe the necessary features MVC/CT demands from the Data Binding mechanism. Then we show three different approaches with their pros and cons for realizing the Data Binding mechanism in MVC/CT. All three approaches are acceptable for MVC/CT.6.9.1 Data Binding CharacteristicsAs MVC/CT especially supports HUICA, the Presentation Model has to be really a hierarchical one. This means that any value access is required to automatically hi-erarchically “bubble up” the path of ancestor Components up to the root Compo-nent. This way View Components have the values of all Model Components in their ancestor path at hand in “their” logical Presentation Model. This is a very essential feature in practice to prevent explicit extra data replications (and necessary up-dates on invalidation) along the ancestor path.Additionally, the Data Binding has to support bidirectional bindings for at least the Data Value aspect, automatic loop breaking in case the same value is set again, and a bootstrapping mode by performing the data binding operation once initially without any value change. Finally, the Data Binding should be flexible enough to A bidirectional Data Bind-ing mechanism is abso-lutely essential to MVC/CT. Without this, too much boilerplate code will occur in practice.Figure 6.27: MVC/CT Step 7: Presentation ActioningParameterValuesStateValuesDataValuesBusinessModelBusinessLogicEventValuesPresentationProvisioningPresentationActioningModelControllerServiceObservableObservableObservablePresentationModelPresentationControlBusinessServiceSVDVEVPPPABMBLBSPCPMCommandValuesPVCVData Binding of Presentation Model165support value conversions on-the-fly to keep the amount of Presentation Model val-ues to a minimum and to reduce the amount of Presentation Logic code.6.9.2 Simple Approach: Imperative CodeThe simple approach for MVC/CT Data Binding is through imperative code. For in-stance, the following bidirectionally binds an input field to its Presentation Model value with the help of jQuery:/* foo.view.js */ class View { render () { /* uni-directional VM to PM binding */ $(“input.foo”).on(“change”, (ev) => { cs(this).value(“dataFoo”, $(ev.target).val()) }) /* uni-directional PM to VM binding */ cs(this).observe(“dataFoo”, (val) => { $(“input.foo”).val(val) }) [...] } })The pro of this approach is that this is possible with nearly zero framework support. The con is obvious: one needs a half dozen lines of code for a single Presentation Model value.6.9.3 Clean Approach: Declarative External MappingsThe clean approach for MVC/CT Data Binding is through an external declarative mapping with the help of a Domain-Specific Language (DSL) which follows the se-lection/rule approach of CSS. For instance, the same bidirectional Data Binding with the help of BindingJS [Rummel 2014] could then look like:/* foo.view.bd */ input.foo { /* bi-directional VM to PM binding */ %value <-> $dataFoo }The pro of this approach is the perfect Separation of Concerns, the conciseness and expressiveness, and the similarity to CSS in the context of HTML5 SPAs. The con of this approach is that it requires a data binding framework which can be in conflict with the usual View Mask template framework, as it basically operates on the same level.CoChapter 6: Solution166More elaborative examples of such a declarative Data Binding follow to illus-trate the expressiveness of this powerful approach. The first example is the pos-sible Data Binding for a list of person entities. /* data binding a list of entities */ div.person-list { ul (length($dataPersons) > 0) { li (@person, @k: slice(sort(“name”, $dataPersons), $paramWindowBegin, $paramWindowEnd)) { %attr:data-id <- @person.id span.pos { %text <- $paramWindowBegin + @k } span.name { %text <- @person.name } } } div.none (length($dataPersons) == 0) { %text <~ i18n(lang = $stateGlobalLang, id = “no-persons-available”) } }The second is the possible Data Binding for a stateful login dialog where both username and password fields have associated error hints and the login button state depends on both entered username and password fields and no associated errors./* data-binding a login dialog */ input[name=”username”] { %class:disabled <- !$stateUsernameEnabled %on:change, %on:keypress +> %value -> debounce(100) -> $dataUsername %value <- $dataUsername } div.username-error { %attr:display <- ($stateUsernameError != “” ? “block” : “none”) %text <- $stateUsernameError } input[name=”password”] { %class:disabled <- !$statePasswordEnabled %on:change, %on:keypress +> %value -> debounce(100) -> $dataPassword %value <- $dataPassword } div.password-error { %attr:display <- ($statePasswordError != “” ? “block” : “none”) %text <- $statePasswordError } button.login { %attr:name <~ i18n(lang = $stateGlobalLang, Data Binding of Presentation Model167 id = “button-login”) %class:disabled <- ( $dataUsername != “” && $stateUsernameError == “” && $dataPassword != “” && $statePasswordError == “”) %on:click +> true -> $eventLoginRequested }In this DSL the %foo identifiers bind to the View Mask, the $foo identifi-ers bind to the Presentation Model, the @foo identifiers are variables local to the Data Binding mechanism only and the foo() identifiers are func-tions provided by the Data Binding mechanism itself. The “<->” operator performs bi-directional Data Binding, the “<-” and “->” operators per-form uni-directional Data Binding, the “<~” and “~>” operators perform one-time uni-directional Data Binding which trigger at most once at all, and the “<+” and “+>” operators perform uni-directional Data Binding where the source (the “initiator”) just triggers a Data Binding update, but does not provide the values itself.6.9.4 Pragmatic Approach: Declarative Inline ExpressionsIn practice, a more pragmatic approach is reasonable: to use declarative inline ex-pressions within the View Mask itself. With the popular VueJS framework this looks like this:/* foo.view.html */ <div> [...] <input class=”foo” v-model=”dataFoo” [...]></input> [...] </div>The pro of this approach is that it combines the declarative Data Binding expres-sions with the usual View Mask template mechanism and is very convenient and popular in practice. The con is that there is no fully clean Separation of Concerns from an architectural point of view. Nevertheless, this approach is the most popu-lar in practice today as it provides a reasonable balance between expressiveness, conciseness, and pragmatism.The example of the possible Data Binding of a list of person entities looks like this with VueJS:<!-- data binding a list of entities --> <div class=”person-list”> <ul v-if=”dataPersons.length > 0”> <li v-for=”(person, k) in dataPersonsSortedAndSliced” v-bind:data-id=”person.id”> <span class=”pos”>{{ k }}</span> <span class=”name”>{{ person.name }}</span> </li> </ul> An external mapping with a CSS-resembling DSL has the benefit that it is both easy to under-stand and very concise and expressive.Chapter 6: Solution168 <div class=”none” v-if=”dataPersons.length == 0”> {{ i18n({ lang: stateGlobalLang, id: ”no-persons-available” }) }} </div> </div>6.9.5 Model Read/Write Operations and Binding UpdatesFor the Data Binding mechanism to work, three aspects have to be taken into ac-count: ■Track Read and Write Operations: read and write operations to both the View Mask and the Presentation Model have to be tracked on the basis of DOM elements and Presentation Model fields. For this, the DOM and the Presentation Model usually support the Observer pattern [Gamma et al. 1994]. ■Match Write and Read Operations: for each write operation, all related read operations are checked. If a write and read operation pair overlap in their DOM element or Presentation Model field, the write operation is considered to outdate the read operation. ■Trigger Repetition of Read Operations: for each outdated read operation, the operation is repeated to transfer the underlying (new) value.6.10 Data Binding of Business ModelA good model guides your thinking, a bad one warps it. — Brian MarickThe Data Binding between the Presentation Model and the Business Model is secondary, but nevertheless important for MVC/CT. It happens primarily in the Controller Component’s Presentation Provisioning as-pect. First, we describe the necessary features MVC/CT demands from the Business Model Data Binding mechanism. Then we show three dif-ferent approaches with their pros and cons for realizing the Business Model Data Binding mechanism in MVC/CT. All three approaches are acceptable for MVC/CT.6.10.1 Data Binding CharacteristicsAs the Business Model stays in the Back End in a Rich Client Architecture, the Busi-ness Model Data Binding in the Front End has to be asynchronous, of course. Addi-tionally, it has to support selectively extracting data to allow the Controller Compo-nent of a UI Fragment to just fetch the actually required data. It also should support The Data Binding for the Business Model is sec-ondary, but still essen-tial in HUICA to provide true Reactive UIs where multiple clients can col-laboratively work on the Business Model data in parallel.Data Binding of Business Model169flexible data aggregation, splitting and transformation, because the Presentation Model usually has a different structure than the Business Model. Finally, it should support paging (loading just a window of the data result set) and real-time updates not to be the bottleneck in MVC/CT.6.10.2 Simple Approach: Imperative CodeThe simple approach for Business Model Data Binding in MVC/CT is through im-perative code. For instance, the following unidirectionally provisions fields of the Presentation Model with the help of jQuery and a REST API at the Back End./* foo.ctrl.js */ $.get(`/api/Users/${id}`).then((user) => { $.get(`/api/Users/${id}/orgUnit`).then((orgUnit) => { let name = `${user.firstname} ${user.lastname}` cs(this, “model”).value(“dataName”, name) cs(this, “model”).value(“dataOrg”, orgUnit.name) }) })The pro of this approach is that it is straightforward. The con of this approach is that more data is transferred than actually required.6.10.3 Clean Approach: Declarative External MappingsThe clean approach for Business Model Data Binding in MVC/CT is through a declarative mapping with the help of a Domain-Specific Language (DSL). As no implementation of this approach currently exists, a fictive example would be:/* foo.ctrl.bd */ user := Users#$id orgUnit := user.orgUnit dataName <- user.firstname + “ “ + user.lastname dataOrg <- orgUnit.nameThe pro of this approach is the reduction to just the essential information. The con is just that still no implementation exists. 6.10.4 Pragmatic Approach: Declarative Inline QueriesThe pragmatic approach for Business Model Data Binding in MVC/CT is through an embedded query language which allows extracting just the necessary data from the Back End. An example based on GraphQL would be:/* foo.ctrl.js */ graphql(`query ($id: ID) { user: Users (id: $id) { firstname GraphQL is very appeal-ing to developers, as que-ries directly resemble the expected JSON results in their structure.Next >