Enhance Web Development
Angular 2
Architecture composant
Architecture composant
- Système d'architecture composant
- Contrat @Input et @Output
- @Input
- @Output
- Composant intelligent ou stupide
- Encapsulation de vue
Bref historique Angular
Salut Angular 1.x
Petite app = petite vue + petit controller
Mmmh ...
Grosse vue
Gros controlleur
Grosse application
What?
Enorme vue
Enorme controlleur
Enorme application
Deux solides approches
Les routes nommées
Large app 1.x
Routes
nommées
Routes
nommées
Routes
nommées
Les directives
Large app 1.x
Directive
Directive
Directive
Les composants
Toutes les app ng2
Component
Component
Component
Système d'architecture composant
- Les composants son de petit bout du logiciel qui peuvent être réutilisable dans différents contextes
- Angular 2 et la communauté encouragent vivement ce type d'architecture pour rapidement développer, tester et deployer des fonctionnalités.
- Un composant Angular est autonome au niveau du template, du style et de sa logique
Data binding
Data binding personnalisé
Contrat @Input & @Output
- Un contrat est un engagement entre deux parties: Le développeur et l'utilisateur - ou - le vendeur avec l'acheteur
- @Input et @Output definissent l'interface d'un composant
- Pour utiliser un composant, on se renseigne sur ces entrées et sorties
Contrat composant
<div>
<item-detail
(saved)="saveItem($event)"
(cancelled)="resetItem($event)"
[item]="selectedItem">Select an Item</item-detail>
</div>
Contrat composant
@Input
- Créer un canal de communication depuis un composant parent vers un composant enfant (top-down)
- Décorer une propriété directement dans le composant : @Input() someValue: string
- On crée le lien dans le parent via un property binding : <component [someValue]="value"></component>
- On peut également différencier le nom de la propriété et le nom du lien dans le template :
@Input('aliasName') someValue: string
import { Component, Input } from 'angular2/core';
@Component({
selector: 'my-component',
template: `
<div>Greeting from parent:</div>
<div>{{greeting}}</div>
`
})
export class MyComponent {
@Input() greeting: String = 'Default Greeting';
}
@Input
import { Component } from 'angular2/core'
import { MyComponent } from './components/my.component'
@Component({
selector: 'app',
template: `
<my-component [greeting]="greeting"></my-component>
<my-component></my-component>
`,
directives: [ MyComponent ]
})
export class App {
greeting: String = 'Hello child!'
}
@Input
@Output
- Expose une propriété de type EventEmitter qui permet de partager les évènement avec le composant parent
- Définition identique à @Input avec un décorateur directement dans le composant :
@Output() showValue: new EventEmitter<boolean> - Le lien avec le parent se fait via un event binding
<component (someValue)="handleValue()"></component>
import { Component, Output, EventEmitter } from 'angular2/core'
@Component({
selector: 'my-component',
template: `<button (click)="greet()">Greet Me</button>`
})
export class MyComponent {
@Output() greeter: EventEmitter = new EventEmitter()
greet() {
this.greeter.emit('Child greeting emitted!')
}
}
@Output
import {MyComponent} from './my-component'
@Component({
selector: 'app',
template: `
<div>
<h1>{{greeting}}</h1>
<my-component (greeter)="greet($event)"></my-component>
</div>
`,
directives: [MyComponent]
})
export class App {
greet(event) {
this.greeting = event;
}
}
@Output
Composant intelligent ou stupide
- Les composants intelligents sont :
- connecté à des services
- Ils savent où chercher leur propres données et comment persister ces données
- Les composants stupide sont :
- Complètement définie par leurs bindings
- Toutes leurs données transite via @Input et @Output
- TIPS : Créer peu de composants intelligents et beaucoup de composants stupide
export class ItemsList {
@Input() items: Item[];
@Output() selected = new EventEmitter();
@Output() deleted = new EventEmitter();
}
Composant stupide
export class App implements OnInit {
items: Array<Item>;
selectedItem: Item;
constructor(private itemsService: ItemsService) {}
ngOnInit() { }
resetItem() { }
selectItem(item: Item) { }
saveItem(item: Item) { }
replaceItem(item: Item) { }
pushItem(item: Item) { }
deleteItem(item: Item) { }
}
Composant Intelligent
Encapsulation de vue
- Cela permet de cloisonner l'inclusion de style
- Il existe (pour l'instant ...) trois types d'encapsulation :
- viewEncapsulation.None : les styles sont globaux à l'application
- viewEncapsulation.Emulated : les styles sont cloisonnées en utilisant un attribut unique sur le composant HTML
- viewEncapsulation.Native : les styles sont cloisonnées en utilisant le shadow DOM natif
Encapsulation de vue
import { Component, Output, EventEmitter } from 'angular2/core'
@Component({
selector: 'my-component',
template: `<button (click)="greet()">Greet Me</button>`,
encapsulation: ViewEncapsulation.None // or ViewEncapsulation.Emulated or ViewEncapsulation.Native
})
export class MyComponent {
@Output() greeter: EventEmitter = new EventEmitter()
greet() {
this.greeter.emit('Child greeting emitted!')
}
}
Demo time !
Défi
- Créer un composant stupide widgets-list et item-details en utilisant @Input et @Output
- Utiliser le service widgets
- Consumer la collection de widgets et la faire transiter vers le composant widgets-list
- Sélectionner un widget depuis la widgets-list
- Afficher la sélection dans item-details
Linalis - 07 - Architecture composant
By Benjamin LONGEARET
Linalis - 07 - Architecture composant
- 823