Input

1. Property Binding

Pour transmettre des données à un "child component", nous allons communiquer avec ce dernier de la même façon que nous contrôlons les propriétés d'un élément natif, c'est à dire à l'aide du Property Binding :

<wt-book-preview [book]="bookList[0]"></wt-book-preview>

On obtient alors un "set" implicite de la propriété book de l'instance du composant BookPreviewComponent.

Sous le capot
Sous le capot
bookPreviewComponent.book = this.bookList[0];

Remarquez la similarité avec le Property Binding sur des éléments natifs.

<button [disabled]="!isEnabled">
button.disabled = !this.isEnabled;

2. Déclaration de la propriété

Avec le code précédent, nous obtenons l'erreur suivante :

Template parse errors:
Can't bind to 'book' since it isn't a known property of 'wt-book-preview'.
1. If 'wt-book-preview' is an Angular component and it has 'book' input, then verify that it is part of this module.
2. If 'wt-book-preview' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

En effet, le composant book-preview n'a pas de propriété book. Il faut donc la déclarer :

book-preview.component.ts
book-preview.component.ts
...
export class BookPreviewComponent {
book: Book;
}

... mais heureusement, cela ne suffit pas et nous obtenons toujours la même erreur.

3. Décorateur @Input()

Par défaut, aucune propriété de composant ne peut être modifiée par Property Binding. Il faut donc définir les propriétés pouvant servir d' "input" au composant en ajoutant simplement le décorateur @Input().

book-preview.component.ts
book-preview.component.ts
import { Input } from '@angular/core';
​
...
export class BookPreviewComponent {
@Input() book: Book;
}

Voyez ce décorateur comme un contrôle vous permettant de définir la visibilité d'une propriété d'un composant.

N'oubliez pas les parenthèses !

En réalité, Input est une "factory" qui retourne un décorateur. Si vous l'utilisez comme décorateur @Input book, elle n'aura aucune action et ne fonctionnera donc pas.

Résultat

app.component.ts
app.component.ts
...
export AppComponent {
bookList = [
new Book({
title: 'eXtreme Programming Explained'
}),
new Book({
title: 'ReWork'
})
];
}
app.component.html
app.component.html
<wt-book-preview
*ngFor="let book of bookList"
[book]="book"></wt-book-preview>
book-preview.component.ts
book-preview.component.ts
...
export class BookPreviewComponent {
book: Book;
}
book-preview.component.html
book-preview.component.html
<div>{{ book.title }}</div>