Input dan Output — Angular

Input dan Output adalah cara komponen berkomunikasi di Angular. @Input() — Data dari Parent ke Child // child.component.ts @Component({ selector: "app-card"…

Input dan output adalah cara dua komponen bicara. Input membawa data dari komponen induk (parent) ke komponen anak (child): App memberi tahu kartu menu nama dan harganya. Output membawa kejadian dari anak ke induk: kartu memberi tahu App "ada yang memesan aku". Bayangin kartu menu kosong di Martabak Bang Jali. Bang Jali (App) menulis nama dan harga di tiap kartu, itu input. Tiap kartu punya bel kecil bertuliskan Pesan; saat dibunyikan, Bang Jali mendengar dan menaruh martabaknya ke keranjang, itu output.

🧪 Tebakan cepat: App menulis <app-menu-item [nama]="Martabak Telur Spesial" />, tanpa tanda kutip tunggal di dalamnya. Apa yang tampil di kartu? Jawabannya ada di bagian "Kurung siku membaca kode, bukan teks".

@Input(): App mengisi kartu

// src/app/menu-item/menu-item.ts
import { Component, Input } from '@angular/core'

@Component({
  selector: 'app-menu-item',
  standalone: true,
  template: `
    <div class="kartu">
      <h3>{{ nama }}</h3>
      <p>Rp{{ harga }}</p>
    </div>
  `,
})
export class MenuItem {
  @Input() nama = ''
  @Input() harga = 0
}
<!-- template App, dengan imports: [MenuItem] -->
@for (m of menu; track m.id) {
  <app-menu-item [nama]="m.nama" [harga]="m.harga" />
}
menu = [
  { id: 1, nama: 'Martabak Manis Cokelat Keju', harga: 40000 },
  { id: 2, nama: 'Martabak Telur Spesial', harga: 50000 },
  { id: 3, nama: 'Terang Bulan Pandan', harga: 35000 },
]

Latihan memakai bentuk yang sama:

@Component({
  selector: 'app-greeting',
  standalone: true,
  template: `<h2>Halo, {{ nama }}!</h2>`,
})
export class GreetingComponent {
  @Input() nama = ''
}

Di editor latihan, komponen ini dijalankan sendirian tanpa induk, jadi yang tampil Halo, !: gak ada yang mengirim nama, dan nilai awalnya teks kosong. Itu wajar.

Kurung siku membaca kode, bukan teks

Isi [nama]="..." dibaca sebagai kode TypeScript, sama seperti {{ }}. Jadi:

Ditulis di App Yang diterima kartu
[nama]="m.nama" isi properti m.nama
[nama]="'Martabak Telur Spesial'" teks Martabak Telur Spesial
nama="Martabak Telur Spesial" teks yang sama, tanpa kurung siku
[pesan]="Halo" properti App bernama Halo, yang gak ada, jadi kosong
[nama]="Martabak Telur Spesial" gak ada: template gagal dikompilasi

Tiga kata tanpa tanda kutip bukan kode yang sah, jadi Angular 18 menolak seluruh template App: Parser Error: Unexpected token 'Telur' at column 10 in [Martabak Telur Spesial]. Kartunya gak tampil, bahkan judul App pun gak. Itu jawaban tebakannya. Untuk teks, pakai tanda kutip tunggal di dalam tanda kutip ganda, atau buang kurung sikunya.

@Output(): kartu memberi tahu App

// di MenuItem: tambahkan Output dan EventEmitter ke import
@Output() pesan = new EventEmitter<string>()

pesanIni() {
  this.pesan.emit(this.nama)
}
// template kartu: <button (click)="pesanIni()">Pesan</button>
<!-- template App -->
<app-menu-item [nama]="m.nama" [harga]="m.harga" (pesan)="tambahKeKeranjang($event)" />
<p>Keranjang: {{ keranjang.join(', ') }}</p>
keranjang: string[] = []

tambahKeKeranjang(nama: string) {
  this.keranjang = [...this.keranjang, nama]
}
Kejadian $event Tampil
Render pertama Keranjang:
Pesan di kartu Terang Bulan Pandan 'Terang Bulan Pandan' Keranjang: Terang Bulan Pandan
Pesan di kartu Martabak Telur Spesial 'Martabak Telur Spesial' Keranjang: Terang Bulan Pandan, Martabak Telur Spesial

Data mengalir satu arah

Input cuma mengalir turun. Kalau kartu mengubah this.nama miliknya sendiri, cuma kartu itu yang berubah: menu di App tetap sama. Begitu App mengganti nilainya, Angular menimpa salinan di kartu dengan nilai baru dari App. Jadi anak yang ingin mengubah data milik induk gak mengubahnya sendiri, tapi meng-emit output dan membiarkan induknya yang mengubah, seperti tambahKeKeranjang tadi.

💡 Opsi @Input: required dan transform

@Input({ required: true }) nama!: string
@Input({ transform: booleanAttribute }) favorit = false

💡 Bentuk signal: input() dan output()

nama = input('')
harga = input.required<number>()
pesan = output<string>()

⚠️ Jebakan yang sering ketemu

TL;DR: @Input() nama = '' membuat properti yang diisi induk lewat [nama]="m.nama"; isi kurung siku dibaca sebagai kode, jadi teks butuh tanda kutip tunggal ([pesan]="'Halo'" mengirim Halo) atau tanpa kurung siku sama sekali. @Output() pesan = new EventEmitter<string>() plus this.pesan.emit(this.nama) mengirim kejadian ke atas, dan induknya mendengarkan dengan (pesan)="tambahKeKeranjang($event)", di mana $event adalah nilai yang di-emit. Data mengalir turun lewat input, kejadian naik lewat output. input() dan output() adalah bentuk signal-nya untuk proyek Angular CLI.

Yang akan kamu pelajari