Pada modul ini kita akan tambahkan fitur service, dengan memindahkan event listener ketika item recipe dipilih.
Buka file recipe.service.ts, tambahkan property recipeSelected.
import { EventEmitter } from "@angular/core";
import { Recipe } from "./recipe.model";
export class RecipeService{
//tambahkan property untuk menangkap event recipe click.
recipeSelected = new EventEmitter<Recipe>();
private recipes: Recipe[] = [
new Recipe('Oreo Dorayaki 1', 'Doriyaki dengan bahan utama Oreo', 'https://i.ytimg.com/vi/nJGmdqb892Y/maxresdefault.jpg' ),
new Recipe('Oreo Dorayaki 2', 'Doriyaki dengan bahan utama Oreo', 'https://i.ytimg.com/vi/nJGmdqb892Y/maxresdefault.jpg' )
];
getRecipes(){
return this.recipes.slice();
}
}
Kemudian buka file recipe-list.component.ts, lakukan modifikasi
- Buang EventEmiter, karena akan dipindahkan ke RecipeService.
- Ubah method onSelect(), dengan memindahkan penggunaan EventEmiter ke service.
- Hapus import EventEmitter dan Output karena sudah tidak digunakan.
//hapus EventEmitter dan Output
import { Component, EventEmitter, OnInit, Output } from '@angular/core';
import { Recipe } from '../recipe.model';
import { RecipeService } from '../recipe.service'; // RecipeService
@Component({
selector: 'app-recipe-list',
templateUrl: './recipe-list.component.html',
styleUrls: ['./recipe-list.component.css']
})
export class RecipeListComponent implements OnInit {
//dibuang karena sudah dipindah ke service.
//@Output() recipeSelected = new EventEmitter<Recipe>();
recipes!: Recipe[];
constructor(private recipeService: RecipeService) { }
ngOnInit(): void {
this.recipes = this.recipeService.getRecipes();
}
//event akan dibinding ke Service
onSelect(recipe: Recipe){
//pindahkan ke service
//this.recipeSelected.emit(recipe);
this.recipeService.recipeSelected.emit(recipe);
}
}
Kemudian buka file recipes.component.ts, lalukan modifikasi berikut:
- Hapus import library yang sudah tidak digunakan (library Input).
- Gunakan property tanpa menggunakan directive Input().
- Akses instance RecipeService melalui constructor.
- Akses perubahan recipe pada method ngOnInit().
//hapus import Input karena sudah tidak digunakan
import { Component, OnInit, Input} from '@angular/core';
import { Recipe } from './recipe.model';
import { RecipeService } from './recipe.service';
@Component({
selector: 'app-recipes',
templateUrl: './recipes.component.html',
styleUrls: ['./recipes.component.css'],
providers: [RecipeService]
})
export class RecipesComponent implements OnInit {
//tidak digunakan karena sudah dipindah ke service
//@Input() recipeSelected! : Recipe;
//ganti menjadi property
recipeSelected! :Recipe;
//akses instance RecipeService
constructor(private recipeService : RecipeService) { }
//mengakses perubahan recipe yang diclick.
ngOnInit(): void {
this.recipeService.recipeSelected.subscribe(
(recipe: Recipe) => { this.recipeSelected = recipe;}
);
}
// method dihapus karena sudah menggunakan ke service
// onRecipeSelected(recipe : Recipe){
// this.recipeSelected = recipe;
// }
}
Kemudian buka file recipes.component.html, ubah penggunakan component app-recipe-list, karena sudah tidak perlu menggunakan event binding.
<div class="row">
<div class="col-md-5">
<!-- Penggunaan component diubah, tidak perlu event binding -->
<!-- <app-recipe-list (recipeSelected)=" onRecipeSelected($event)"></app-recipe-list> -->
<app-recipe-list></app-recipe-list>
</div>
<div class="col-md-7">
<app-recipe-detail
*ngIf="recipeSelected; else tempText"
[recipe]="recipeSelected"
>
</app-recipe-detail>
<ng-template #tempText><p>Please select recipe..</p></ng-template>
</div>
</div>
Sesuai ekspektasi, recipe detail ditampilkan sesuai dengan recipe yang dipilih. Perbedaanya sekarang melalui service.
Dapat dilihat, kode component menjadi lebih ramping. Passing data menjadi tidak rumit.