Декоратори @input та @output в Angular
Спілкування компонентів
Компоненти Angular спілкуються через декоратори @Input (батько → дитина) та @Output (дитина → батько). Це основний механізм взаємодії компонентів.
@Input — Від батька до дитини
typescript
// child.component.ts
@Component({
selector: 'app-user-card',
template: \`
<div class="card">
<h3>{{ name }}</h3>
<p>Вік: {{ age }}</p>
<p>Роль: {{ role }}</p>
</div>
\`
})
export class UserCardComponent {
@Input() name = '';
@Input() age = 0;
@Input() role: 'admin' | 'user' = 'user';
@Input({ required: true }) id!: string;
}html
<!-- parent.component.html -->
<app-user-card
[name]="user.name"
[age]="user.age"
[role]="user.role"
[id]="user.id"
/>Перетворення вхідних даних
typescript
@Component({ /* ... */ })
export class MyComponent {
@Input({ transform: booleanAttribute }) disabled = false;
@Input({ transform: numberAttribute }) count = 0;
}html
<!-- Рядок "true" → логічне true -->
<app-my disabled count="5" />@Output — Від дитини до батька
typescript
// child.component.ts
@Component({
selector: 'app-search-box',
template: \`
<input
[value]="query"
(input)="onInput($event)"
(keyup.enter)="onSearch()"
>
<button (click)="onSearch()">Пошук</button>
<button (click)="onClear()">Очистити</button>
\`
})
export class SearchBoxComponent {
@Output() search = new EventEmitter<string>();
@Output() clear = new EventEmitter<void>();
query = '';
onInput(event: Event) {
this.query = (event.target as HTMLInputElement).value;
}
onSearch() {
this.search.emit(this.query);
}
onClear() {
this.query = '';
this.clear.emit();
}
}html
<!-- parent.component.html -->
<app-search-box
(search)="handleSearch($event)"
(clear)="handleClear()"
/>typescript
// parent.component.ts
handleSearch(query: string) {
console.log('Шукаємо:', query);
}
handleClear() {
console.log('Пошук очищено');
}Вхідні дані на основі сигналів (Angular 17+)
typescript
@Component({ /* ... */ })
export class UserCardComponent {
// Вхідні дані на основі сигналів (сучасний підхід)
name = input.required<string>();
age = input(0);
role = input<'admin' | 'user'>('user');
// Обчислюється з вхідних даних
isAdult = computed(() => this.age() >= 18);
greeting = computed(() => \`Привіт, \${this.name()}!\`);
}Вихідні дані з функцією output() (Angular 17+)
typescript
@Component({ /* ... */ })
export class SearchBoxComponent {
search = output<string>();
clear = output<void>();
onSearch(query: string) {
this.search.emit(query);
}
}Підсумок
| Напрямок | Декоратор | Синтаксис |
|---|---|---|
| Батько → Дитина | @Input() / input() | [property]="value" |
| Дитина → Батько | @Output() / output() | (event)="handler($event)" |
| Двосторонній | @Input() + @Output() | [(property)]="value" |
Важливо:
@Input передає дані вниз від батька до дитини. @Output з EventEmitter надсилає події вгору від дитини до батька. В Angular 17+ віддавайте перевагу вхідним даним на основі сигналів (input()) та функції output() для кращої типізації та реактивності. Це основний шаблон спілкування компонентів в Angular.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.