In questo capitolo ci dedicheremo alla visualizzazione dei dati di un singolo record, nel nostro caso di un singolo prodotto. La premessa è contenuta nella lezione precedente, dove abbiamo impostato il link tramite routerLink
e specificato la rotta e l'id del prodotto come parametro.
Il primo passo sarà quello di creare il component dedicato alla visualizzazione del singolo prodotto, tramite la CLI possiamo facilmente raggiungere questo obiettivo:
ng g component prodotti/read-one-product
Questa istruzione creerà i file per la gestione del component e in particolare la classe e il template HTML.
Il prossimo passaggio sarà quello di aggiornare il file di routing prevedendo la rotta che dovrà contenere il passaggio del parametro. Quindi nel file app.routes.ts
aggiungiamo l'import del component:
import {ReadOneProductComponent} from './prodotti/read-one-product/read-one-product.component';
E nelle rotte vere e proprie l'associazione:
{path:'dettaglio/:id', component:ReadOneProductComponent},
Dove :id
è il nome del parametro.
Passiamo ora alla classe ReadOneProductComponent
dove importare il service e la classe Product
come già fatto per la lista dei prodotti, anche se dovremo poi implementare un metodo specifico nel service:
import { ProdottitService } from '../../prodotti.service';
import { Product } from '../../prodotto';
Inoltre dovremo importare l'oggetto ActivetedRoute
che ci servirà per la lettura del parametro preso dall'URL:
import { ActivatedRoute } from '@angular/router';
Implementiamo il metodo nel service che andrà a richiamare la nostra API PHP e tramite questa il database; la struttura della chiamata sarà simile a quella per la lista dei prodotti, uniche differenze saranno il parametro d'ingresso alla funzione e l'oggetto restituito: un singolo oggetto e non un array
Il codice da aggiungere al service è il seguente:
readOneProduct(product_id): Observable{
return this._http
.get("http://localhost/phprest/api/v1/prodotti/"+product_id)
.map(res => res.json());
}
Ora abbiamo quello che serve per completare il component. Importiamo l'OnInit
per implementare l'interfaccia OnInit
e gestire l'evento dell'inizializzazione del component:
import { Component, OnInit } from '@angular/core';
…
export class ReadOneProductComponent implements OnInit {
Poi definiamo due proprietà della nostra classe: una per l'id del prodotto e l'altra per la risposta:
product_id: number;
product: Product;
Al costruttore passeremo il service e l'oggetto ActivetedRoute
importato in precedenza:
constructor(private route:ActivatedRoute, private productService: ProductService){}
A questo punto all'evento OnInit
andremo a leggere il parametro passato tramite URL:
ngOnInit(){
this.route.params.subscribe(params => {
this.product_id=params['id'];
});
E lo memorizziamo nella proprietà product_id
. Ora possiamo chiamare il metodo del service prima definito:
this.productService.readOneProduct(this.product_id)
.subscribe(product => this.product=product);
}
Quando arriva la risposta dal Web server, all'interno della proprietà product
memorizzeremo il JSON ottenuto in risposta, a questo punto non resta che mappare i dati sul template HTML e la pagina sarà completa.
Il template HTML
Il binding
dei dati verrà fatto tramite interpolazione, quindi il template HTML sarà il seguente:
<section>
<div class="row">
<div class="col-md-12">
<a routerLink="/home" class='btn btn-primary pull-right'>
<span class='glyphicon glyphicon-list'></span> Lista prodotti
</a>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table">
<tr>
<td>Nome</td>
<td>{{product.nome}}</td>
</tr>
<tr>
<td>Prezzo</td>
<td>{{product.prezzo}}</td>
</tr>
<tr>
<td>Descrizione</td>
<td>{{product.descrizione}}</td>
</tr>
<tr>
<td>Categoria</td>
<td>{{product.categoria_nome}}</td>
</tr>
</table>
</div>
</div>
</section>