Scenario : Let say you want to populate the dropdown on component 2 when there is a change in value of dropdown present in component 1
==============================================================================
First of all we have to check the relation between different components
1. Parent (component 1) > Child (Component 2) - Sharing data via @input
2. Child (component 1) > Parent (Component 2) -Sharing Data via Output() and EventEmitter
3. Siblings with common parent. Child 1(component 1) > Child 2 (Component 2) -- use of both @output and @input together
4. Totally unrelated components -- Sharing data with service, Sharing data with Route, NgRX
==============================================================================
1. Parent > Child
Sharing data via @input decorator.
import { Component } from '@angular/core';@Component({selector: 'parent-component',template: `<child-component [childProperty]="parentProperty"></child-component>`,styleUrls: ['./parent.component.css']})export class ParentComponent{parentProperty = "I come from parent"constructor() { }}
child.component.ts
import { Component, Input } from '@angular/core';@Component({selector: 'child-component',template: `Hi {{ childProperty }}`,styleUrls: ['./child.component.css']})export class ChildComponent {@Input() childProperty: string;constructor() { }}
==============================================================================
2. Child > Parent
Sharing Data via Output() and EventEmitter
parent.component.ts
import { Component } from '@angular/core';@Component({selector: 'parent-component',template: `Message: {{message}}<child-component (messageEvent)="receiveMessage($event)"></child-component>`,styleUrls: ['./parent.component.css']})export class ParentComponent {constructor() { }message:string;receiveMessage($event) {this.message = $event}}
child.component.ts
import { Component, Output, EventEmitter } from '@angular/core';@Component({selector: 'child-component',template: `<button (click)="sendMessage()">Send Message</button>`,styleUrls: ['./child.component.css']})export class ChildComponent {message: string = "Hello!"@Output() messageEvent = new EventEmitter<string>();constructor() { }sendMessage() {this.messageEvent.emit(this.message)}}
==============================================================================
3. Siblings with common parent. Child 1(component 1) > Child 2 (Component 2)
parent.component.ts
import { Component } from '@angular/core';@Component({selector: 'parent-component',template: `Message: {{message}}<child-one-component (messageEvent)="receiveMessage($event)"></child1-component><child-two-component [childMessage]="message"></child2-component>`,styleUrls: ['./parent.component.css']})export class ParentComponent {constructor() { }message: string;receiveMessage($event) {this.message = $event}}
child-one.component.ts
import { Component, Output, EventEmitter } from '@angular/core';@Component({selector: 'child-one-component',template: `<button (click)="sendMessage()">Send Message</button>`,styleUrls: ['./child-one.component.css']})export class ChildOneComponent {message: string = "Hello!"@Output() messageEvent = new EventEmitter<string>();constructor() { }sendMessage() {this.messageEvent.emit(this.message)}}
child-two.component.ts
import { Component, Input } from '@angular/core';@Component({selector: 'child-two-component',template: `{{ message }}`,styleUrls: ['./child-two.component.css']})export class ChildTwoComponent {@Input() childMessage: string;constructor() { }}
==============================================================================
4. Totally unrelated components
Sharing Data with a Service
When passing data between components that lack a direct connection, such as siblings, grandchildren, etc, you should be using a shared service. When you have data that should always be in sync, I find the RxJS BehaviorSubject very useful in this situation.
data.service.ts
import { Injectable } from '@angular/core';import { BehaviorSubject } from 'rxjs';@Injectable()export class DataService {private messageSource = new BehaviorSubject('default message');currentMessage = this.messageSource.asObservable();constructor() { }changeMessage(message: string) {this.messageSource.next(message)}}
first.component.ts
import { Component, OnInit } from '@angular/core';import { DataService } from "../data.service";@Component({selector: 'first-componennt',template: `{{message}}`,styleUrls: ['./first.component.css']})export class FirstComponent implements OnInit {message:string;constructor(private data: DataService) {// The approach in Angular 6 is to declare in constructorthis.data.currentMessage.subscribe(message => this.message = message);}ngOnInit() {this.data.currentMessage.subscribe(message => this.message = message)}}
second.component.ts
import { Component, OnInit } from '@angular/core';import { DataService } from "../data.service";@Component({selector: 'second-component',template: `{{message}}<button (click)="newMessage()">New Message</button>`,styleUrls: ['./second.component.css']})export class SecondComponent implements OnInit {message:string;constructor(private data: DataService) { }ngOnInit() {this.data.currentMessage.subscribe(message => this.message = message)}newMessage() {this.data.changeMessage("Hello from Second Component")}}
==============================================================================
No comments:
Post a Comment