Зачем использовать @Output в Angular?
Я новичок в Angular, и я не понимаю, зачем мне нужен @Output для отправки данных в родительский компонент. Я пытался использовать @Input derective для передачи функции, как мы делаем это в React, и это работает. Родитель:
@Component({
selector: 'app-root',
template: `
<app-top-bar [func]="funcFromParent" [data]="dataFromParent"></app-top-bar>
`,
})
export class AppComponent {
funcFromParent: () => void;
dataFromParent: string;
constructor() {
this.dataFromParent = '';
this.funcFromParent = function () {
this.dataFromParent = 'Hi';
};
}
}
объект-дочка:
@Component({
selector: 'app-top-bar',
templateUrl: './top-bar.component.html',
styleUrls: ['./top-bar.component.css'],
})
export class TopBarComponent {
@Input() func: Function = () => {};
@Input() data: string = '';
}
Пример дочернего шаблона:
<button (click)="func()">ttt</button>
<div>
<p>{{ data }}</p>
</div>
Ответы (2 шт):
Во-первых, в Angular есть название для потока данных: Input и Output - входные и выходные параметры. Что также является удобным для понимания того, с каким параметром мы имеем дело.
Во-вторых, у вас может не быть входных параметров в компоненте или директиве.
В-третьих, шаблоны в Angular подразумевают специальный синтаксис под события дочерних элементов, тогда как передача функции и обработка ее событий через Input потребует от вас сделать собственные обработчики таких событий. Таже не исключена потеря контекста. Плюс, потребует продумать передачу данных в ту функцию, которую вы будете передавать в Input, тогда как Output легко поддерживает передачу аргументов.
В целом, Input и Output - это части фреймворка, которые дали разработчики, чтобы строить приложение согласно их идее. Если вы до этого пользовались другим фреймворком, то не стоит пытаться сделать из нового фреймворка - старый. Для каждой задачи есть свой инструмент и нужно использовать его.
Допустим в вашем компоненте есть два элемента - поле ввода и кнопка. И вы хотите, чтобы при нажатии на кнопку, куда-то во вне, передавалось значение из этого поля ввода. Для таких случаев и нужен @Output при помощи которого внешние компоненты-слушатели могут получать необходимые значения.
Таким образом достигается разделение ответственности компонентов приложения. Одни - поставляют данные, а другие их получают и используют для своих нужд, третьи-десятые, например, - взаимодействюут с сервером. То есть, каждый компонент занят своим делом и все стремится подчиниться простым рекомендациям для создания гибких, расширяемых и поддерживаемых приложений (SOLID)
ts вашего компонента-поставщика данных:
export class MyComponent {
@Output() onInputData = new EventEmitter<string>();
buttonClicked(): void {
this.onInputData.emit(inputText);
}
}
В другом компоненте:
html:
<app-my-component (onInputData)="onInputData($event)"></app-my-component>
ts:
export class ServerCommunication {
// Метод-слушатель. Вызывается при нажатии на кнопку в компоненте MyComponent
onInputData(inputData: string): void {
this.serverService.sendInputData(inputData).subscribe(...);
}
}