by Gion Kunz
Founder, UI Developer, UX Enthusiast at syncrea GmbH
./projects/my-app └── src ├── app │ ├── components │ │ ├── common │ │ │ └── layout-container │ │ ├── payment │ │ │ └── payment-modal │ │ ├── product │ │ │ └── product-details │ │ └── shell │ │ └── app ...
... │ ├── containers │ │ ├── app-container │ │ ├── payment-container │ │ └── product-container ...
./projects/my-app
└── src
├── app
│ ├── app.module.ts
│ ├── components
│ │ ├── common
│ │ │ └── main-layout
│ │ │ └── main-layout.component.ts
│ │ ├── payment
│ │ │ └── payment-modal
│ │ │ └── payment-modal.component.ts
│ │ ├── product
│ │ │ └── product-details
│ │ │ └── product-details.component.ts
│ │ └── shell
│ │ └── app
│ ├── containers
│ │ ├── app-container
│ │ │ └── app-container.component.ts
│ │ ├── payment-container
│ │ │ └── payment-container.component.ts
│ │ └── product-container
│ │ │ └── product-container.component.ts
│ ├── guards
│ │ ├── product.guard.ts
│ │ └── payment.guard.ts
│ ├── helpers
│ │ └── helpers.ts
│ ├── model
│ │ └── model.ts
│ ├── pipes
│ ├── services
│ │ ├── payment.service.ts
│ │ └── product.service.ts
│ ├── state
│ │ ├── app
│ │ │ ├── actions.ts
│ │ │ ├── effects.ts
│ │ │ ├── reducers.ts
│ │ │ └── state.ts
│ │ ├── payment
│ │ │ ├── actions.ts
│ │ │ ├── effects.ts
│ │ │ ├── reducers.ts
│ │ │ └── state.ts
│ │ └── product
│ │ ├── actions.ts
│ │ ├── effects.ts
│ │ ├── reducers.ts
│ │ └── state.ts
│ └── tokens.ts
├── assets
├── index.html
├── main.ts
├── polyfills.ts
├── routes.ts
└── styles
└── styles.scss
@Component({
selector: 'user-profile',
template: `
<p class="name">{{name}}</p>
`
})
class UserProfile {
@Input() name;
}
Container Component
Data
Data
Action
Action
10%
Container Components
90% Presentational Components
import {ServerProduct, Product} from '../../model/model';
import {convertServerProduct} from '../../helpers/helpers';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private http: HttpService) {}
loadProducts(): Product[] {
return this.http.get<ServerProduct[]>('').pipe(
map(serverProducts => serverProducts.map(convertServerProduct))
);
}
}
...
export function calculateTotalPrice(products: Product[]): number {
return products
.filter(product => product.selected)
.reduce((totalPrice, product) => totalPrice + product.price, 0);
}
export function isAdult(person: Person, now: Date): boolean {
return !!person.birthdate && getAge(person.birthdate, now) >= 18;
}
...
Data
Persistance
Application and Business Logic
Application State
Obtain State and Trigger Actions
Presentation and View Logic
Angular Services
Helper module with pure functions
Any state management framework (e.g. ngrx, redux etc.)
Container Components
Pure Presentational Components
Data
Persistance
Application and Business Logic
Application State
Obtain State and Trigger Actions
Presentation and View Logic
Very simple Angular services which only connect to remote API's
Depends on state management framework. Only handful of containers.
Depends on view rendering capabilities of Angular.