Обмен данными между родительским и дочерним компонентом (Angular component interaction)
@input
@output
Decorators
Event emitter
C помощью декораторов @Input, @Output и API EventEmitter можно обеспечить обмен данными между родительскими и дочерними компонентами.
Декоратор @Input
Дочерний компонент с помощью декоратора input может получать данные от родительского, а с помощью декоратора output - посылать.
Для получения данных от родительского компонента дочерним:
- в дочернем компоненте создаём свойство, в которое данные будем получать, декорируем его с помощью декоратора @Input
- в родительском компоненте создаём public - свойство, которое будем передавать
- при вызове дочернего компонента через созданное нами свойство привязываем к свойству дочернего компонента данные из родительского.
Родительский компонент:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
public string1 = <string> 'Data from parent...';
}
Шаблон родительского компонента - вызов дочернего:
<h1>This is parent component:</h1>
<hr>
<app-inoutcomponent [inFromParent]='string1'></app-inoutcomponent>
Дочерний компонент
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-inoutcomponent',
templateUrl: './inoutcomponent.component.html',
styleUrls: ['./inoutcomponent.component.css']
})
export class InoutcomponentComponent implements OnInit {
@Input() public inFromParent: string;
constructor() { }
ngOnInit() {
}
}
Шаблон дочернего компонента
<h1>This is child component:</h1>
<h3>{{inFromParent}}</h3>
Результат
Добавим в родительский компонент метод, который меняет это свойство. Привяжем его к событию click кнопки.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
public string1 = <string> 'Data from parent...';
changeChildData() {
this.string1 += ' Changed ';
}
}
При каждом нажатии к строке будем приписывать текст: this.string1 += ' Changed ';
Результат после 2-х кликов:
Декоратор @Output и EventEmitter
Передача данных от дочернего компонента к родительскому.
Для этого используем декоратор @Output и привяжем к дочернеиу компоненту обработчик событий, который инициирует эту передачу.
У дочернего компонета создаём своё событие - outToParent (объект класса EventEmitter ), декорируя его декоратором @Output.
Создадим в дочернем компоненте метод - sendToParent() . Его задача: передать событие родительскому объекту (метод emit()).
Передано это событие будет через Angular объект - $event.
Таким образом, созданное нами событие - outToParent произойдёт в тот момент, когда сработает sendToParent()и его (события) содержимое можно будет получить из $event.
Дочерний компонент
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-inoutcomponent',
templateUrl: './inoutcomponent.component.html',
styleUrls: ['./inoutcomponent.component.css']
})
export class InoutcomponentComponent implements OnInit {
@Input() public inFromParent: string;
@Output() public outToParent = new EventEmitter();
constructor() { }
ngOnInit() {
}
sendToParent() {
this.outToParent.emit('Child sent this message to parent...');
}
}
Привяжем обработчик событий - click к кнопке в шаблоне дочернего компонента и по этому клику вызовем метод sentToParent, который в свою очередь включит событие outToParent:
Шаблон дочернего компонента
<h1>This is child component:</h1>
<h3>{{inFromParent}}</h3>
<br>
<button (click)='sendToParent()'>Click to send data!</button>
<br>
Стиль дочернего компонента
* {
color: green;
}
Родительский компонент получает данные события методом, который мы в нём создали - getNessage()
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
public string1 = <string> 'Data from parent...';
public string2 = '';
changeChildData() {
this.string1 += ' Changed ';
}
receiveFromChild(evnt){
this.string2 = evnt;
}
}
Шаблон родительского компонента (outToParent - новое событие, которое мы создали)
<h1>This is parent component:</h1>
<button (click)='changeChildData()'>Change child data </button>
<hr>
<strong>{{string2}}</strong>
<app-inoutcomponent (outToParent)='receiveFromChild($event)' [inFromParent]='string1'></app-inoutcomponent>
До клика
После клика
Декоратор @Component, свойства - inputs, outputs
Вместо использования декораторов свойств - @Input и @Outpur можно использовать свойства декоратора класса - @Component (inputs, outputs).
import { Component, OnInit, EventEmitter } from '@angular/core';
// import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-inoutcomponent',
templateUrl: './inoutcomponent.component.html',
styleUrls: ['./inoutcomponent.component.css'],
inputs: ['inFromParent'],
outputs:['outToParent']
})
export class InoutcomponentComponent implements OnInit {
// @Input() public inFromParent: string;
inFromParent: string;
// @Output() public outToParent = new EventEmitter();
outToParent = new EventEmitter();
constructor() { }
ngOnInit() {
}
sendToParent() {
this.outToParent.emit('Child sent this message to parent...');
}
}
Но Angular рекомендуют использовать @Input и @Output
https://angular.io/guide/styleguide#style-05-12)%20(use-output-property-decorator
style 05-12