@seanox/aspect-js
Version:
full stack JavaScript framework for SPAs incl. reactivity rendering, mvc / mvvm, models, expression language, datasource, virtual paths, unit test and some more
290 lines (231 loc) • 9.36 kB
Markdown
[Resource-Bundle](message.md) | [Inhalt](README.md#model-view-controller) | [SiteMap](sitemap.md)
- - -
# Model-View-Controller
Der Model-View-Controller (MVC) ist ein Entwurfsmuster zur Trennung von
Interaktion, Daten und Darstellung. Hier muss zwischen I/O-Controller und
Applikations-Controller unterschieden werden. Das reine MVC-Entwurfsmuster meint
den I/O-Controller zur Übermittlung der Interaktionen. Da dies von
Betriebssystem und Browser übernommen wird, bezieht sich Seanox aspect-js
vordergründig auf den Applikations-Controller.
```
+------------------------------------------+--------------+-----------------------+
| View | Controller | Model |
+------------------------------------------+--------------+-----------------------+
| Markup | Composite | JavaScript |
| | Reactive | |
+------------------------------------------+--------------+-----------------------+
| <form id="model" composite> | aspect-js | const model = { |
| <input id="message" events="input"/> | | message: "", |
| <button id="submit"/> | | submit: { |
| </form> | | onClick() { |
| | | } |
| | | } |
| | | } |
+------------------------------------------+--------------+-----------------------+
```
## Model
Models sind statische JavaScript-Objekte, die vergleichbar mit managed Beans und
DTOs (Data Transfer Objects) Daten, Zustände und Funktionen für die
View bereitstellen. Als Singletons/Facades/Delegates können sie weitere
Komponenten und Abstraktionen nutzen, selbst Geschäftslogik enthalten und
sind ein Bindeglied zwischen View und Middleware. Das erforderliche
View-Model-Binding ist Bestandteil vom Composite-API, was im Abschnitt
[Model-View-Controller - Binding](mvc.md#binding) detailliert beschrieben wird.
## View
Die View, welche durch das Markup repräsentiert wird, ist ausschliesslich
für die Darstellung bzw. Projektion von Modellen verantwortlich. Wobei
Projektion eine gute Beschreibung ist, da die Art der Darstellung eines Modells
nicht eingeschränkt ist.
## Controller
Der (Applikations-)Controller steuert Abläufe innerhalb einer Applikation
(Face-Flow) und übernimmt mit dem View-Model-Binding den Datenfluss
zwischen View und Model, wobei hier auch von MVVM (Model-View-ViewModel) und
MVCS (Model-View-Controller-Service) gesprochen werden kann.
## Inhalt
* [Model](#model)
* [View](#view)
* [Controller](#controller)
* [View-Model-Binding](#view-model-binding)
* [Composite](#composite)
* [Binding](#binding)
* [Dock](#dock)
* [Undock](#undock)
* [Synchronization](#synchronization)
* [Validation](#validation)
* [Events](#events)
## View-Model-Binding
Das View-Model-Binding übernimmt die bidirektionale Verknüpfung der
HTML-Elemente der View mit den Modellen als statische JavaScript-Objekte und
organisiert so den Datenfluss, kommuniziert Ereignisse sowie Zustände und
bindet Funktionen an.
### Composite
Die Grundlage für das View-Model-Binding bilden Composites, was funktional
eigenständige Komponenten sind, die sich aus Markup, CSS und JavaScript
sowie optional aus weiteren Ressourcen zusammensetzen. Die Bindung alle
Bestandteile erfolgt über die auch als Composite-ID bezeichnete ID vom
HTML-Konstrukt, dem namensgleichen Model im JavaScript sowie der zum HTML
korrespondierenden ID im CSS.
```html
<html>
<head>
<script src="aspect-js.js"></script>
</head>
<body>
<div id="example" composite></div>
</bod>
</html>
```
```javascript
const example = {
...
}
```
```css
#example {
...
}
```
Die Composite-ID ist somit ein eindeutiger Bezeichner innerhalb der Anwendung.
Sie ist eine Zeichenfolge, die aus Buchstaben, Zahlen und Unterstrichen besteht,
mindestens ein Zeichen lang ist, mit einem Unterstrich oder einem Buchstaben
beginnt und sich durch die Kombination der Attribute `id` und `composite` bei
einem HTML-Element bildet.
Composites oder besser deren Composite-ID, definieren den Punkt im globalen
Objektbaum, wo sich das korrespondierende JavaScript-Model befindet. Alle von
einem Composite eingeschlossenen HTML-Elemente mit einer ID werden dann im
korrespondierenden JavaScript-Model als Zweige reflektiert, wenn diese im Model
entsprechend implementiert sind.
```javascript
const model = {
message: "Hello",
submit: {
...
}
};
```
```html
<html>
<body>
<form id="model" composite>
<input type="text" id="message"/>
<input type="submit" id="submit"/>
...
</form>
</body>
</html>
```
### Binding
Beim View-Model-Binding geht es um die Verbindung von Markup/HTML (View) mit dem
entsprechenden JavaScript-Objekt (Model). Das Binding leitet Interaktionen und
Statusänderungen der View an das Model weiter und stellt eine
Schnittstelle für Middleware-Funktionen und Services für die View bereit.
Womit keine manuelle Implementierung von Ereignissen, Synchronisation und
Interaktion zwischen View und Anwendungslogik erforderlich ist.
```javascript
const model = {
message: "Hello",
submit: {
onClick(event) {
...
}
}
};
```
```html
<html>
<body>
<form id="model" composite>
<input type="text" id="message" value="{{model.message}}" events="change"/>
<input type="submit" id="submit"/>
...
</form>
</body>
</html>
```
### Dock
Wird ein Composite im DOM verwendet/eingefügt, wird das entsprechende
JavaScript-Objekt (Model) angedockt/verknüpft und beim Entfernen aus dem
DOM abgedockt/entknüpft. In beiden Fällen kann das Modell optional
geeignete Methoden implementieren. Die Methode `dock` wird vor dem Rendern, vor
dem Einfügen des Composites in das DOM oder nach dem Laden der Seite beim
ersten Rendern ausgeführt und kann zur Vorbereitung der Darstellung
verwendet werden. Die Methode `undock` wird ausgeführt, nachdem das
Composite aus dem DOM entfernt wurde und kann zur Nachbereitung bzw. Bereinigung
der Darstellung verwendet werden.
```javascript
const model = {
dock() {
...
},
undock() {
...
}
};
```
```html
<html>
<body>
<div id="model" composite>
...
</div>
</body>
</html>
```
Bei Composites, die mit dem Attribut [condition](markup.md#condition) deklariert
werden, hängt der Aufruf der Methoden vom Ergebnis der Bedingung ab.
### Undock
Details werden im Abschnitt [Dock](#undock) beschrieben.
### Synchronization
Das View-Model-Binding umfasst neben der statischen Verknüpfung und
Zuordnung von HTML-Elementen (View) zum JavaScript-Objekt (Model) auch die
Synchronisation von Werten zwischen den HTML-Elementen und den Feldern im
JavaScript-Objekt. Die Synchronisation hängt von Ereignissen ab, die
für das HTML-Element mit dem Attribut [events](markup.md#events) deklariert
sind und wird nur ausgeführt, wenn eines der definierten Ereignisse
eintritt.
Details zur Funktionsweise werden im Abschnitt [events](markup.md#events)
beschrieben.
### Validation
Die Synchronisation der Werte zwischen den HTML-Elementen (View) und den Feldern
vom JavaScript-Objekt (Model) kann durch Validierung überwacht und
gesteuert werden. Die Validierung wird in HTML durch die Kombination der
Attribute [validate](markup.md#validate) und [events](markup.md#events)
deklariert und erfordert eine entsprechende Validierungsmethode im
JavaScript-Objekt.
Details zur Funktionsweise werden im Abschnitt [validate](markup.md#validate)
beschrieben.
### Events
Ereignisse, genauer gesagt die Interaktion zwischen View und Modell, werden beim
View-Model-Binding ebenfalls berücksichtigt. Die Methoden zur Interaktion
werden nur im Model implementiert. Im Markup selbst ist keine Deklaration
erforderlich. Das View-Model-Binding kennt die verfügbaren Ereignisse im
HTML und so wird beim Binding das Model nach entsprechenden Methoden durchsucht,
die dann als Event-Listener registriert werden.
```javascript
const contact = {
mail: {
onClick(event) {
const mail = "mailto:mail@local?subject=Test&body=Greetings";
document.location.href = mail;
return false;
}
}
};
```
```html
<html>
<body>
<div id="contact" composite>
<p>
Example for use of events.
</p>
<button id="mail">
Click Me!
</button>
</div>
</body>
</html>
```
- - -
[Resource-Bundle](message.md) | [Inhalt](README.md#model-view-controller) | [SiteMap](sitemap.md)