Philip Schmökel, Tim Lüecke, Marek Matczak
(a.k.a. TI-Architecture)
... are the predominant architecture of the past.
The content of each web page is fully rendered on the server.
Each action requires a round trip to the server which contains presentation logic and application state.
A page's content is retrieved with a single page load.
The page does not reload any more.
(a.k.a. T-Architecture)
... commonly called Reactive Architecture or Flux
But is this really sufficient for building large scalable applications?
... here are a few questions.
How to structure huge applications?
How is the data converted from model to view?
Where does Internationalization happen?
What about validation of user input?
How does the client talk to the application core?
What about dialog states and widget states?
What about states that are dependent on other states?
How to design state controlling if an action can be executed or not?
How does the model look exactly?
Projects gone wrong. Let's look at a few examples.
It's done! Does it work in IE? Err... Avoid rolling your own if there is a library!
Browser tab grows to 2GB, unresponsive script warnings. Dialogs were not unloaded.
Unlimited loading of data to the client. Do paging, filtering, sorting, and grouping on the server side!
Mass manipulation in the DOM caused unnecessary rendering of intermediate results (forced reflow). Render at the end!
Methods reused at the wrong level cause duplicate calls and performance issues. Event listeners triggering new events are hard to debug. Avoid!
What we are trying to achieve, is a maintainable and performant client.
For that we need to handle its static and dynamic complexity.
Split applications into functional components handling a specific functional concern.
Features of components
On the client components are called dialogs.
Car configurator could then be reused for public website.
The container is responsible for the configuration, lifecycle-management and bootstrapping of the dialogs and client application.
Mostly provided by framework, but might need to be extended.
Dialog components interact by either embedding each other or forwarding the control flow to each other.
This meta architecture maps to MVC, MVP, MVVM...
The devonfw Client Architecture is a meta-architecture for architectures based on a concrete framework:
Mapping the Dialog Container...
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
angular.json
// Import Statement
import { environment } from '../../../environments/environment';
// Usage
this.http.get<Flight[]>(environment.backendUrl + '/flights');
The import statement does not change when changing the environment.
When Angular compiler creates HeaderComponent injectors are asked until the dependency can be found or root injector can not handle
Angular Modules help to structure the client
core.module contains shared services.
share.module contains shared components.
A feature module encapsulates dialog components and functionality of one business domain.
Note: Multiple dialog components can be part of a feature module.
A Dialog Component is typically an Angular toplevel component, that is activated by a route.
A must-know pattern: Smart vs Dumb Components
Smart Components | Dumb Components |
contain the current view state | show data via `@Input` binding and contain no view state |
handle events emited by _Dumb Components_ | pass events up the component tree to be handled by _Smart Components_ (`@Output`) |
subscribe to application state from stores | never use stores |
consists of n _Dumb Components_ | is independent of _Smart Components_ |