komunikacja @Input

omówię:

- jak przesłać dane z komponetu rodzica do komponentu dziecka
- jak korzystać z adnotacji @Input

Popracujmy nad tym aby stworzyć reużywalny komponent, który reprezentuje kartę danego samochodu.

W konsoli w głównym folderze projektu wpisz polecenie: 

ng g c card

Gdy przejdziesz do pliku app.module.ts powinieneś zobaczyć dodany CardComponent.

 
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {MatButtonModule, MatCardModule} from '@angular/material';
import { CardComponent } from './card/card.component';

@NgModule({
declarations: [
AppComponent,
CardComponent // <-----
],
imports: [
BrowserModule,
BrowserAnimationsModule,
MatCardModule,
MatButtonModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Przejdz do pliku app.component.ts oraz skopiuj kod odpowiedzialny za wystwietlenie pojedynczej karty i wklej go do pliku card.component.html.

<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/3-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>

W tym momencie możesz już korzystać z komponentu card.component natomiast nie jest on jeszcze reużwyalny.

w pliku app.component.html dodaj tag html’owy który opisuje komponent card.component <app-card>

<div class="main-container">
<app-card></app-card>
<app-card></app-card>
<app-card></app-card>

<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/3-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/4-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/5-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/6-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/7-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="https://www.szkolaangulara.pl/wp-content/uploads/2020/05/8-small.jpeg"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>
</div>

W pliku car.component.scss dodaj następujący kod

:host {
max-width: 30%;
margin: 5px;
}

.example-header-image {
background-size: cover;
}

Przejdz do pliku app.component.scss i w klasie main-container dodaj wpis justify-content: space around. Dzięki temu karty ułożą się równomiernie na dashboardzie głównym.

.example-card {
max-width: 30%;
margin: 5px;
}

.example-header-image {
background-size: cover;
}


.main-container {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}

Powinieneś zobaczyć następujący widok

Efekt jaki chcielibyśmy uzyskać to możliwośc reużywania karty poprzez możliwość przekazywania różnych danych. 

Do przekazywania danych z poziomu rodzica (app.component.html) do dziecka (card.component.html) służy adnotacja @Input

Stwórzmy zmienną, która będzie przyjmowała namiar na odpowiednie zdjęcie.

W pliku card.componet.ts dodaj nastepujący kod

import {Component, Input} from '@angular/core';

@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent {
@Input()
public photoSource: string;
}

Następnie połącz zmienną photoSource z komponentu w szablonie html. 

Aby użyć zmiennej z komponentu w szablonie html musisz skorzystać z tzw. mechanizmu bindowania danych. W tym przypadku w miejscu src dodaj podwójne nawiasy klamrowe {{}} oraz wewnątrz podaj nazwę zmiennej: {{photoSource}}.

Przejdź do pliku card.component.html oraz dodaj następujący kod

<mat-card class="example-card">
<mat-card-header>
<div mat-card-avatar class="example-header-image"></div>
<mat-card-title>Shiba Inu</mat-card-title>
<mat-card-subtitle>Dog Breed</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="{{photoSource}}"
alt="Photo of a Shiba Inu">
<mat-card-content>
<p>
The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
bred for hunting.
</p>
</mat-card-content>
<mat-card-actions>
<button mat-button>LIKE</button>
<button mat-button>SHARE</button>
</mat-card-actions>
</mat-card>

Tak przygotowany komponenty musimy jeszcze zasilić odpowiednimi danymi. Przejdz do pliku app.component.html oraz przekaż do komponentu app-card zmienna photoSource. 

Plik app.component.html możesz zastąpić poniższym kodem

<div class="main-container">
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/3-small.jpeg'">
</app-card>
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/4-small.jpeg'">
</app-card>
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/5-small.jpeg'">
</app-card>
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/6-small.jpeg'">
</app-card>
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/7-small.jpeg'">
</app-card>
<app-card
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/8-small.jpeg'">
</app-card>
</div>

Nauczyłeś się właśnie jak stworzyć reużywalny komponent i jak przekazywać do niego różne dane. Popracujmy teraz nad tym aby karta przyjmowała więcej zmiennych. 

W card.component.ts dodaj poniższy kod

import {Component, Input} from '@angular/core';

@Component({
selector: 'app-card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent {
@Input()
public photoSource: string;
@Input()
public title: string;
@Input()
public subtitle: string;
@Input()
public description: string;
}

dostosuj card.component.html

<mat-card class="example-card">
<mat-card-header>
<mat-card-title>{{title}}</mat-card-title>
<mat-card-subtitle>{{subtitle}}</mat-card-subtitle>
</mat-card-header>
<img mat-card-image src="{{photoSource}}">
<mat-card-content>
<p>{{description}}</p>
</mat-card-content>
<mat-card-actions>
<button mat-raised-button color="primary">WYBIERZ</button>
</mat-card-actions>
</mat-card>

Przejdź do pliku app.component.html

<div class="main-container">
<app-card
[title]="'Audi'"
[subtitle]="'RS7'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/3-small.jpeg'"
[description]="'Pierwszy właściciel. Polski salon. Przebieg: 75 000 km'">
</app-card>
<app-card
[title]="'Mercedes'"
[subtitle]="'GT'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/4-small.jpeg'"
[description]="'Pierwszy właściciel. Polski salon. Przebieg: 25 000 km'">
</app-card>
<app-card
[title]="'Audi'"
[subtitle]="'A3'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/5-small.jpeg'"
[description]="'Pierwszy właściciel. Polski salon. Przebieg: 63 000 km'">
</app-card>
<app-card
[title]="'Mercedes'"
[subtitle]="'Klasa G'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/6-small.jpeg'"
[description]="'Pierwszy właściciel. Polski salon. Przebieg: 13 000 km'">
</app-card>
<app-card
[title]="'BMW'"
[subtitle]="'Seria 3'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/7-small.jpeg'"
[description]="'Drugi właściciel. Przebieg: 125 000 km'">
</app-card>
<app-card
[title]="'Nissan'"
[subtitle]="'370z'"
[photoSource]="'https://www.szkolaangulara.pl/wp-content/uploads/2020/05/8-small.jpeg'"
[description]="'Drugi właściciel. Przebieg: 74 000 km'">
</app-card>
</div>