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.