सबसे पहले, आपको घटकों के बीच संबंधों को समझने की आवश्यकता है। तब आप संचार का सही तरीका चुन सकते हैं। मैं उन सभी तरीकों की व्याख्या करने की कोशिश करूंगा जो मैं जानता हूं और घटकों के बीच संचार के लिए अपने अभ्यास में उपयोग करता हूं।
घटकों के बीच किस प्रकार के संबंध हो सकते हैं?
1. जनक> बाल
इनपुट के माध्यम से डेटा साझा करना
यह संभवतः डेटा साझा करने का सबसे आम तरीका है। यह @Input()
टेम्पलेट के माध्यम से डेटा को पारित करने की अनुमति देने के लिए डेकोरेटर का उपयोग करके काम करता है ।
parent.component.ts
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() { }
}
यह एक बहुत ही सरल विधि है। यह प्रयोग करने में आसान है। हम ngOnChanges का उपयोग करके बाल घटक में डेटा में परिवर्तन भी पकड़ सकते हैं ।
लेकिन यह मत भूलो कि यदि हम किसी ऑब्जेक्ट को डेटा के रूप में उपयोग करते हैं और इस ऑब्जेक्ट के मापदंडों को बदलते हैं, तो इसका संदर्भ नहीं बदलेगा। इसलिए, यदि हम एक बच्चे के घटक में एक संशोधित वस्तु प्राप्त करना चाहते हैं, तो यह अपरिवर्तनीय होना चाहिए।
2. बच्चा> जनक
ViewChild के माध्यम से डेटा साझा करना
ViewChild एक घटक को दूसरे में इंजेक्ट करने की अनुमति देता है, जिससे माता-पिता अपनी विशेषताओं और कार्यों तक पहुंच प्राप्त कर सकते हैं। हालाँकि, एक चेतावनी, यह child
तब तक उपलब्ध नहीं होगी जब तक कि दृश्य आरंभ नहीं हो जाता। इसका मतलब है कि हमें बच्चे से डेटा प्राप्त करने के लिए AfterViewInit जीवनचक्र हुक को लागू करने की आवश्यकता है।
parent.component.ts
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";
@Component({
selector: 'parent-component',
template: `
Message: {{ message }}
<child-compnent></child-compnent>
`,
styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {
@ViewChild(ChildComponent) child;
constructor() { }
message:string;
ngAfterViewInit() {
this.message = this.child.message
}
}
child.component.ts
import { Component} from '@angular/core';
@Component({
selector: 'child-component',
template: `
`,
styleUrls: ['./child.component.css']
})
export class ChildComponent {
message = 'Hello!';
constructor() { }
}
आउटपुट () और 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. भाई बहन
बाल> अभिभावक> बाल
मैं नीचे भाई-बहनों के बीच संवाद करने के अन्य तरीके समझाने की कोशिश करता हूँ। लेकिन आप पहले से ही उपरोक्त तरीकों को समझने के तरीकों में से एक को समझ सकते हैं।
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
}
}
बच्चों के 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)
}
}
बच्चों के 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. असंबंधित घटक
नीचे बताए गए सभी तरीकों का उपयोग घटकों के बीच संबंध के लिए उपरोक्त सभी विकल्पों के लिए किया जा सकता है। लेकिन प्रत्येक के अपने फायदे और नुकसान हैं।
एक सेवा के साथ डेटा साझा करना
ऐसे घटकों के बीच डेटा पास करते समय जिनमें एक सीधा संबंध नहीं होता है, जैसे कि भाई-बहन, नाती-पोते, आदि, तो आपको एक साझा सेवा का उपयोग करना चाहिए। जब आपके पास डेटा होता है जो हमेशा सिंक में होना चाहिए, तो मुझे इस स्थिति में RxJS BehaviorSubject बहुत उपयोगी लगता है।
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 constructor
this.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")
}
}
एक रूट के साथ डेटा साझा करना
कभी-कभी आपको न केवल घटक के बीच सरल डेटा को पारित करने की आवश्यकता होती है, बल्कि पृष्ठ की कुछ स्थिति को बचाते हैं। उदाहरण के लिए, हम ऑनलाइन बाज़ार में कुछ फ़िल्टर सहेजना चाहते हैं और फिर इस लिंक को कॉपी करके किसी मित्र को भेज सकते हैं। और हम उम्मीद करते हैं कि यह हमारे जैसे ही राज्य में पेज खोलेगा। पहला, और शायद सबसे तेज़, ऐसा करने का तरीका क्वेरी मापदंडों का उपयोग करना होगा ।
क्वेरी पैरामीटर उन रेखाओं के साथ अधिक दिखते हैं /people?id=
जहां id
कुछ भी समान हो सकता है और आपके पास जितने चाहें उतने पैरामीटर हो सकते हैं। क्वेरी पैरामीटर एम्परसेंड वर्ण द्वारा अलग किया जाएगा।
क्वेरी पैरामीटर के साथ काम करते समय, आपको उन्हें अपने रूट फ़ाइल में परिभाषित करने की आवश्यकता नहीं है, और उन्हें पैरामीटर नाम दिया जा सकता है। उदाहरण के लिए, निम्नलिखित कोड लें:
page1.component.ts
import {Component} from "@angular/core";
import {Router, NavigationExtras} from "@angular/router";
@Component({
selector: "page1",
template: `
<button (click)="onTap()">Navigate to page2</button>
`,
})
export class Page1Component {
public constructor(private router: Router) { }
public onTap() {
let navigationExtras: NavigationExtras = {
queryParams: {
"firstname": "Nic",
"lastname": "Raboy"
}
};
this.router.navigate(["page2"], navigationExtras);
}
}
प्राप्त करने वाले पृष्ठ में, आपको निम्न तरह से ये क्वेरी पैरामीटर प्राप्त होंगे:
page2.component.ts
import {Component} from "@angular/core";
import {ActivatedRoute} from "@angular/router";
@Component({
selector: "page2",
template: `
<span>{{firstname}}</span>
<span>{{lastname}}</span>
`,
})
export class Page2Component {
firstname: string;
lastname: string;
public constructor(private route: ActivatedRoute) {
this.route.queryParams.subscribe(params => {
this.firstname = params["firstname"];
this.lastname = params["lastname"];
});
}
}
NgRx
अंतिम तरीका, जो अधिक जटिल है लेकिन अधिक शक्तिशाली है, NgRx का उपयोग करना है । यह लाइब्रेरी डेटा शेयरिंग के लिए नहीं है; यह एक शक्तिशाली राज्य प्रबंधन पुस्तकालय है। मैं एक छोटे उदाहरण में नहीं बता सकता कि इसका उपयोग कैसे करना है, लेकिन आप आधिकारिक साइट पर जा सकते हैं और इसके बारे में प्रलेखन पढ़ सकते हैं।
मेरे लिए, NgRx Store कई मुद्दों को हल करता है। उदाहरण के लिए, जब आपको वेधशालाओं से निपटना होता है और जब अलग-अलग घटकों के बीच कुछ अवलोकन योग्य डेटा के लिए जिम्मेदारी साझा की जाती है, तो स्टोर क्रिया और reducer सुनिश्चित करता है कि डेटा संशोधनों को हमेशा "सही तरीके" से किया जाएगा।
यह HTTP अनुरोध कैशिंग के लिए एक विश्वसनीय समाधान भी प्रदान करता है। आप अनुरोधों और उनकी प्रतिक्रियाओं को संग्रहीत करने में सक्षम होंगे ताकि आप यह सत्यापित कर सकें कि आप जो अनुरोध कर रहे हैं वह अभी तक संग्रहीत प्रतिक्रिया नहीं है।
आप NgRx के बारे में पढ़ सकते हैं और समझ सकते हैं कि आपको अपने ऐप में इसकी आवश्यकता है या नहीं:
अंत में, मैं कहना चाहता हूं कि डेटा साझा करने के कुछ तरीकों को चुनने से पहले आपको यह समझने की आवश्यकता है कि भविष्य में इस डेटा का उपयोग कैसे किया जाएगा। मेरा मतलब है कि शायद अब आप @Input
एक उपयोगकर्ता नाम और उपनाम साझा करने के लिए सिर्फ एक डेकोरेटर का उपयोग कर सकते हैं । फिर आप एक नया घटक या नया मॉड्यूल जोड़ेंगे (उदाहरण के लिए, एक व्यवस्थापक पैनल) जिसे उपयोगकर्ता के बारे में अधिक जानकारी की आवश्यकता है। इसका मतलब है कि उपयोगकर्ता डेटा या किसी अन्य तरीके से डेटा साझा करने के लिए किसी सेवा का उपयोग करने का एक बेहतर तरीका हो सकता है। डेटा साझाकरण को लागू करने से पहले आपको इसके बारे में अधिक सोचने की आवश्यकता है।