Rispetto a quanto visto in precedenza diverso sarà invece il discorso per la scelta della categoria. In questo caso vogliamo avere una select
popolata dinamicamente con le categorie presenti nel database. Per questo creeremo prima tutta la struttura necessaria, classe e service per le categorie, e quindi procederemo con la chiamata.
Intanto la classe verrà salvata nel file category.ts
:
export class Category {
id: number;
name: string;
description: string;
}
Poi creiamo un nuovo service che conterrà la chiamata alla lista delle categorie con lo schema visto per i prodotti:
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import { Category } from './category';
@Injectable()
export class CategoryService {
constructor(private _http: Http) { }
readCategories(): Observable{
return this._http
.get("http://localhost/phprest/api/v1/categorie/")
.map(res => res.json());
}
}
Aggiorniamo il nostro component importando le ultime due classi create:
import { CategoryService } from '../../category.service';
import { Category } from '../../category';
E aggiungiamo al decoratore il nuovo provider in modo da ottenere questo codice:
@Component({
selector: 'app-create-products',
templateUrl: './create-products.component.html',
styleUrls: ['./create-products.component.css'],
providers: [ProductService, CategoryService]
})
Nella classe predisponiamo una proprietà che sarà un array di oggetti categorie:
categories: Category[];
E passiamo il service al nostro costruttore:
private categoryService: CategoryService,
Ora al OnInit
popoliamo con una chiamata asincrona la proprietà categorie:
ngOnInit(){
this.categoryService.readCategories()
.subscribe(categories => this.categories=categories['records']);
}
Ora siamo pronti per creare dinamicamente la nostra select
nel template HTML:
<tr>
<td>Categoria</td>
<td>
<select formControlName="categoria_id" name="categoria_id" class="form-control">
<option *ngFor="let category of categories" value="{{category.id}}">
{{category.nome}}
</option>
</select>
<div
*ngIf="create_product_form.get('categoria_id').touched && create_product_form.get('categoria_id').hasError('required')"
class="alert alert-danger">
Categoria è obbligatorio.
</div>
</td>
</tr>
La parte interessante è costituita dal tag option
che viene generato dal loop sull'array delle categorie usando l'interpolazione per stampare i valori come già abbiamo visto nella tabella dei prodotti.
Completiamo il form con il pulsante per l'invio che resterà disabilitato fin quando il form non è valido:
<tr>
<td></td>
<td>
<button class="btn btn-primary" type="submit" [disabled]="create_product_form.invalid">
<span class="glyphicon glyphicon-plus"></span> Create
</button>
</td>
</tr>
</table>
</form>
</div>
</div>
</section>
Dobbiamo creare la funzione chiamata dall'evento submit
. Nel component aggiungiamo:
createProduct(){
this.productService.createProduct(this.create_product_form.value)
.subscribe(
product => {
this.router.navigateByUrl('/home');
}
);
}
In pratica la funzione richiama il metodo del service passandogli i valori prelevati dal form, non c'è bisogno di una lettura esplicita perché viene attivato un meccanismo di binding bi-direzionale e quindi i dati sono aggiornati. Alla risposta del server si torna alla lista dei record.