माता-पिता से बच्चे तक एक घटना का उत्सर्जन कैसे करें?


111

मैं वर्तमान में कोणीय 2. उपयोग कर रहा हूँ आम तौर पर उपयोग हम @Output() addTab = new EventEmitter<any>();और फिर addTab.emit()माता-पिता घटक के लिए एक घटना फेंकना।

क्या कोई ऐसा तरीका है जिससे हम इसे माता-पिता से लेकर बच्चे तक के लिए कर सकते हैं?


2
बस बच्चे घटक को इनपुट के रूप में पारित एक अभिव्यक्ति के मूल्य को बदल दें, और बच्चे के घटक को यह मिल जाएगा (और ngOnChann द्वारा सूचित किया जाएगा)। आप एक साझा सेवा का उपयोग करके एक घटना का भी अनुकरण कर सकते हैं जिसमें एक अवलोकन योग्य है।
जेबी निज़ेट

जवाबों:


192

RxJs का उपयोग करते हुए , आप Subjectअपने मूल घटक में घोषणा कर सकते हैं और इसे Observableबाल घटक के रूप में पास कर सकते हैं, बाल घटक को इसके लिए सदस्यता लेने की आवश्यकता है Observable

अभिभावक घटक

eventsSubject: Subject<void> = new Subject<void>();

emitEventToChild() {
  this.eventsSubject.next();
}

अभिभावक एचटीएमएल

<child [events]="eventsSubject.asObservable()"> </child>    

बाल-घटक

private eventsSubscription: Subscription;

@Input() events: Observable<void>;

ngOnInit(){
  this.eventsSubscription = this.events.subscribe(() => doSomething());
}

ngOnDestroy() {
  this.eventsSubscription.unsubscribe();
}

13
साथ ही, इस दृष्टिकोण का उपयोग करके डेटा को घटना के साथ पारित किया जा सकता है। जैसे, this.eventsSubject.next({data});माता-पिता में, फिर this.events.subscribe(({data}) => doSomething(data));बच्चे में।
विंस

2
मैंने सदस्यता समाप्त करने के लिए इस शानदार उत्तर को संपादित किया है। +1
उमर फारूक ख्वाजा

1
शायद एक शुरुआती सवाल यहाँ: क्यों eventsSubjectएक सब्जेक्ट के रूप में इसे सब्सक्राइब करने के बजाय एक ऑब्जर्वेबल में बदला जाए?
जस्टिन मॉर्गन

11
घटनाओं को परिवर्तित करना एक अवलोकन के अनुसार, बच्चे के घटक को अगले कॉल करने के लिए रोकें ()।
ब्लूएनसी

2
इस समाधान के लिए धन्यवाद, यह काम करता है, लेकिन मुझे कंसोल में एक त्रुटि मिल रही है: "core.js: 6185 ERROR TypeError: अपरिभाषित की संपत्ति 'सदस्यता' नहीं पढ़ सकता है" त्रुटि ngOnInit में event.scribe () को इंगित कर रही है बच्चे के घटक: "this.eventsSubscription = this.events.subscribe () => doSomething ());" मैं संस्करणों का उपयोग कर रहा हूं: "@ कोणीय / cli": "~ 9.1.0" और "rxjs"; : "~ 6.5.4"
एडुआर्डो

72

जहाँ तक मुझे पता है, 2 मानक तरीके हैं जो आप कर सकते हैं।

1. @ कप्तान

जब भी माता-पिता में डेटा बदलता है, तो बच्चे को इसके बारे में अधिसूचित किया जाता है। बच्चा उस पर कार्रवाई कर सकता है। यह एक बच्चे के साथ बातचीत करने का मानक तरीका है।

Parent-Component
public inputToChild: Object;

Parent-HTML
<child [data]="inputToChild"> </child>       

Child-Component: @Input() data;

ngOnChanges(changes: { [property: string]: SimpleChange }){
   // Extract changes to the input property by its name
   let change: SimpleChange = changes['data']; 
// Whenever the data in the parent changes, this method gets triggered. You 
// can act on the changes here. You will have both the previous value and the 
// current value here.
}
  1. साझा सेवा अवधारणा

एक सेवा बनाना और साझा सेवा में एक अवलोकन का उपयोग करना। बच्चा इसकी सदस्यता लेता है और जब भी कोई बदलाव होता है, तो बच्चे को सूचित किया जाएगा। यह भी एक लोकप्रिय तरीका है। जब आप इनपुट के रूप में पास किए गए डेटा के अलावा कुछ और भेजना चाहते हैं, तो इसका उपयोग किया जा सकता है।

SharedService
subject: Subject<Object>;

Parent-Component
constructor(sharedService: SharedService)
this.sharedService.subject.next(data);

Child-Component
constructor(sharedService: SharedService)
this.sharedService.subject.subscribe((data)=>{

// Whenever the parent emits using the next method, you can receive the data 
in here and act on it.})

मैंने पहली विधि की कोशिश की और यह कुछ बिंदु तक ठीक काम किया और उसके बाद मुझे एक त्रुटि संदेश मिला जिसमें कहा गया था कि मान अब बदल गया है, पहले यह गलत है और अब यह सच है। इसने मुझे इसके अलावा कोई और स्पष्टीकरण नहीं दिया।
कोड

2
यह देखते हुए कि आप एक एक्सप्रेशनचेंज किए गए हैं। ItHasBeenCheckedError, यह त्रुटि उत्पादन मोड में नहीं डाली जाएगी।
15:13 बजे user1337

<child [data]="inputToChild"> </child>संभवतः <child [data]="(inputToChild)"> </child>परिवर्तन प्राप्त करने के लिए होना चाहिए
दोपहर

28

मूल घटक में आप बच्चे के घटक विधि / चर का उपयोग करने के लिए @ViewChild () का उपयोग कर सकते हैं।

@Component({
  selector: 'app-number-parent',
  templateUrl: './number-parent.component.html'
})
export class NumberParentComponent {
    @ViewChild(NumberComponent)
    private numberComponent: NumberComponent;
    increase() {
       this.numberComponent.increaseByOne();
    }
    decrease() {
       this.numberComponent.decreaseByOne();
    }
} 

अपडेट करें:

कोणीय 8 आगे -

@ViewChild(NumberComponent, { static: false })

4
यह पर्यवेक्षकों के साथ काम करने की तुलना में साफ लगता है। दोष यह है कि बच्चे को ध्यान में रखना होगा। यदि बच्चा उदाहरण के लिए रूटिंग के साथ भरा हुआ है, तो यह विफल numberComponentहो जाएगा जैसा कि होगा undefined
श्यम अगम

1
क्या यह अच्छा अभ्यास है? मैं इस तथ्य से सहमत हूं कि वे पर्यवेक्षकों की तुलना में क्लीनर हैं, लेकिन मैं माता-पिता से बच्चे के चर में हेरफेर करने के बारे में संदेह कर रहा हूं। वैसे भी, यह मेरी जरूरतों के लिए बहुत अच्छा काम किया, धन्यवाद!
ताकतालवी

1
यह एक अच्छी टिप है। ऐसा लगता है कि @ViewChild को Angular 8 में बदल दिया गया है, या कम से कम मुझे ViewChild के विकल्प निर्दिष्ट करने थे। मैंने अपने मामले में इसका उपयोग किया: @ व्यूचाइल्ड (अन्य, {स्थैतिक: गलत}) निजी otherComponent: अन्य;
तोरेंदद

8

माता-पिता को इस इनपुट से बांधने की अनुमति देने के लिए अपने बच्चे के घटक में @Input () डेकोरेटर का उपयोग करें।

बाल घटक में आप इसे इस रूप में घोषित करते हैं:

@Input() myInputName: myType

माता-पिता से एक संपत्ति को एक बच्चे को बाँधने के लिए आपको अपने साथ बाध्यकारी कोष्ठक और उनके बीच आपके इनपुट के नाम को जोड़ना होगा।

उदाहरण :

<my-child-component [myChildInputName]="myParentVar"></my-child-component>

लेकिन सावधान रहें, वस्तुओं को एक संदर्भ के रूप में पारित किया जाता है, इसलिए यदि बच्चे में ऑब्जेक्ट को अपडेट किया जाता है तो माता-पिता का संस्करण भी अपडेट किया जाएगा। इससे कुछ समय के लिए अवांछित व्यवहार हो सकता है। प्राथमिक प्रकारों के साथ मान की प्रतिलिपि बनाई जाती है।

आगे पढ़ने के लिए इसे पढ़ें:

डॉक्स: https://angular.io/docs/ts/latest/cookbook/component-communication.html


1

माता-पिता के भीतर, आप @ViewChild का उपयोग करके बच्चे को संदर्भित कर सकते हैं। जब जरूरत (यानी जब घटना को निकाल दिया जाएगा), तो आप @ViewChild संदर्भ का उपयोग करके माता-पिता से बच्चे में एक विधि निष्पादित कर सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.