Pour créer un composant, on peut utiliser Angular CLI:
# g pour generate
# c pour componant
# child est le nom du composant
# -it pour inline template
# -is pour inline style
ng g c child -it -is
Ou pour le faire manuellement
Créer app/child/child.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>child works!</p>`,
})
export class ChildComponent {}
Et charger le composant dans le module, app/app.module.ts:
+import { ChildComponent } from './child/child.component';
@NgModule({
declarations: [
AppComponent,
+ ChildComponent
],
...
Les composants peuvent inclure d’autres composants (pourvu que le module charge des composants) en ajoutant un élément correspondant au sélecteur du composant souhaité — généralement, un tag.
@Component({
selector: 'app-root',
template: `<h1>Hello World</h1>
<app-child></app-child>`
})
export class AppComponent {
}
Un parent peut passer des propriétés à un composant inclut:
app.component:
@Component({
selector: 'app-root',
template: `<h1>Hello {{ username }}</h1>
<app-child [parentData]="username"></app-child>`
})
export class AppComponent {
username = "Bob";
}
Le composant inclut doit déclarer cette propriété en entrée avec le décorateur de propriété @Input
:
child.component:
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>{{ parentData }}!</p>`,
})
export class ChildComponent {
@Input() public parentData;
}
On peut spécifier un alias pour utiliser un nom de propriété différent dans le composant enfant:
@Component({
selector: 'app-child',
template: `<p>{{ value }}!</p>`,
})
export class ChildComponent {
@Input('parentData') public value;
}
Si on veut intercepter les données passées par le parent (pour executer du code supplémentaire), alors on applique le décorateur @Input sur un setter.
@Component({
selector: 'app-child',
template: `<p>{{ value }}!</p>`,
})
export class ChildComponent {
private _value: string;
get value(): string {
return this._value;
}
set value(val: string) {
this._value = val;
// Trigger the action you want
}
}
Une autre alternative est d’utiliser le lifecycle hook ngOnChanges.
import { Component, OnChanges, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-child',
template: `<p>{{ value }}!</p>`,
})
export class ChildComponent {
@Input('parentData') public value;
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
// value: Object { previousValue: undefined, currentValue: "Bob", firstChange: true }
}
}
Dans le composant enfant:
Déclarer une propriété qui est une instance de EventEmitter
et avec le décorateur @Output
. Appeler la méthode emit
sur cet objet pour déclencher un événement.
child.component:
import { Component, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `<button (click)="handleClick()">Click</button>`,
})
export class ChildComponent {
@Output() public clickEvent = new EventEmitter();
handleClick() {
this.clickEvent.emit('My message');
}
}
Dans le composant parent:
Écouter l’événement personnalisé.
Les données envoyées avec l’événement peuvent être récupérées avec $event.
app.component:
@Component({
selector: 'app-root',
template: `<h1>Hello World</h1>
<app-child (clickEvent)="log($event)"></app-child>`
})
export class AppComponent {
log(data) {
alert(data);
}
}
Le composant parent peut accéder à toutes les propriétés et méthodes publiques d’un composant enfant en utilisant une référence.
child.component.ts:
@Component({
selector: 'app-child',
template: `<p>Child says: {{ username }}</p>`,
})
export class ChildComponent {
username = "Bob"
}
app.component.ts:
@Component({
selector: 'app-root',
template: `<app-child #child></app-child>
<p>Parent says: {{ child.username }}</p>`
})
export class AppComponent {
}
Le composant parent peut également modifier les valeurs des propriétés publiques.
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
selector: 'app-root',
template: `<app-child #child></app-child>
<p>Parent says: {{ child.username }}</p>`
})
export class AppComponent implements AfterViewInit {
@ViewChild('child') child: ChildComponent
ngAfterViewInit() {
this.child.username = 'Alice';
}
}