2016-01-15 23 views
5

पर प्रसारित की गईं, मैं कोणीय 2 में अभिभावक निर्देश के भीतर बाल निर्देशों के सामान्य कोणीय 1.x पैटर्न को कार्यान्वित करना चाहता हूं। यहां मेरी वांछित संरचना है।कोणीय 2 बाल घटक घटनाएं अभिभावक

<foo> 
    <bar>A</bar> 
    <bar>B</bar> 
    <bar>C</bar> 
</foo> 

मैं क्लिक घटनाओं Foo घटक को उत्सर्जित करने के लिए है करने के लिए इन Bar घटकों के लिए करना चाहते हैं। यहाँ

@Component({ 
    selector: 'foo', 
    template: ` 
    <div> 
     <ng-content></ng-content> 
    </div> 
    ` 
}) 
export class Foo { 
    @ContentChildren(Bar) items: QueryList<Bar>; 
} 

और मेरी Bar:

यहाँ मेरी Foo अब तक है

@Component({ 
    selector: 'Bar', 
    template: ` 
    <div (click)="clickity()"> 
     <ng-content></ng-content> 
    </div> 
    ` 
}) 
export class Bar { 
    clickity() { 
    console.log('Broadcast this to the parent please!'); 
    } 
} 

मैं कैसे Foo जब भी अपनी Bars में से एक क्लिक किया जाता है यह सूचना देने के बारे में जाते हैं?

+2

आप '.emit को EventEmitter तरीकों का उपयोग कर सकते हैं()' बार में, और '.subscribe()' फू घटक में। या तो '@ आउटपुट() 'या सेवा के माध्यम से, जैसे [इस उदाहरण] (http://stackoverflow.com/a/34576997/1876949) – Sasxa

+0

@Sasxa क्या आप स्पष्टीकरण दे सकते हैं? मुझे पता है कि बच्चे से माता-पिता से @Output() का उपयोग कैसे करें, लेकिन केवल अगर मैं वास्तव में बच्चे के घटक पर विशेषता डाल सकता हूं। मुझे नहीं पता कि उपयोगकर्ता द्वारा परिभाषित बच्चों के साथ गतिशील रूप से इसे कैसे किया जाए। – Harangue

+1

tbh, मैंने '@Output()' का उपयोग नहीं किया है ... मैं सेवा पसंद करता हूं, मैं इसे दोनों कक्षाओं में आयात करता हूं, एमिटर के एक ही उदाहरण के लिए पूछता हूं और जहां मुझे आवश्यकता है वहां emit/subscribe पंजीकृत करें, मैं कोशिश करूंगा एक मिनट में उदाहरण बनाने के लिए ... – Sasxa

उत्तर

5

अन्य जवाब के हल के लिए एक बहुत ही गरीब काम करता है समस्या। EventEmitters का उपयोग केवल @Outputs के साथ-साथ इस समस्या को कोणीय 2 या आरएक्सजेएस की विशेषताओं में निर्मित निर्भरता इंजेक्शन का लाभ नहीं लेना है।

विशेष रूप से, डीआई का उपयोग न करके, आप खुद को एक परिदृश्य में मजबूर कर रहे हैं जहां आप स्थैतिक वर्ग पर निर्भर घटकों का पुन: उपयोग करते हैं, तो वे सभी एक ही घटनाएं प्राप्त करेंगे, जिन्हें आप शायद नहीं चाहते हैं।

कृपया DI का लाभ उठाकर नीचे दिए गए उदाहरण पर नज़र डालें, एक ही कक्षा को कई बार प्रदान करना आसान है, और अधिक लचीला उपयोग सक्षम करने के साथ-साथ मज़ेदार नामकरण योजनाओं की आवश्यकता से बचने में भी आसान है। यदि आप कई घटनाएं चाहते हैं, तो आप अपारदर्शी टोकन का उपयोग करके इस सरल वर्ग के कई संस्करण प्रदान कर सकते हैं।

कार्य उदाहरण: http://plnkr.co/edit/RBfa1GKeUdHtmzjFRBLm?p=preview

// The service 
import 'rxjs/Rx'; 
import {Subject,Subscription} from 'rxjs/Rx'; 

export class EmitterService { 
    private events = new Subject(); 
    subscribe (next,error,complete): Subscriber { 
    return this.events.subscribe(next,error,complete); 
    } 
    next (event) { 
    this.events.next(event); 
    } 
} 

@Component({ 
    selector: 'bar', 
    template: ` 
    <button (click)="clickity()">click me</button> 
    ` 
}) 
export class Bar { 
    constructor(private emitter: EmitterService) {} 
    clickity() { 
    this.emitter.next('Broadcast this to the parent please!'); 
    } 
} 

@Component({ 
    selector: 'foo', 
    template: ` 
    <div [ngStyle]="styl"> 
     <ng-content></ng-content> 
    </div> 
    `, 
    providers: [EmitterService], 
    directives: [Bar] 
}) 
export class Foo { 
    styl = {}; 
    private subscription; 
    constructor(private emitter: EmitterService) { 
    this.subscription = this.emitter.subscribe(msg => { 
     this.styl = (this.styl.background == 'green') ? {'background': 'orange'} : {'background': 'green'}; 
    }); 
    } 
    // Makes sure we don't have a memory leak by destroying the 
    // Subscription when our component is destroyed 
    ngOnDestroy() { 
    this.subscription.unsubscribe(); 
    } 
} 
+1

यह भी देखें https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service –

+0

हाँ मैंने बाद में कोणीय 2 के साथ बहुत समय बिताया है और यह सही उत्तर है । – Harangue

13

यदि आप @Output() सजावट का उपयोग कर ऐसा नहीं कर सकते हैं तो आप घटकों के बीच डेटा भेजने के लिए एक सेवा का उपयोग कर सकते हैं।

import {EventEmitter} from 'angular2/core'; 

export class EmitterService { 
    private static _emitters: { [channel: string]: EventEmitter<any> } = {}; 
    static get(channel: string): EventEmitter<any> { 
    if (!this._emitters[channel]) 
     this._emitters[channel] = new EventEmitter(); 
    return this._emitters[channel]; 
    } 
} 

आप इसे आयात भी आप फेंकना या एक घटना की सदस्यता के लिए की जरूरत है: यहाँ एक उदाहरण है

// foo.component.ts 
import {EmitterService} from '../path/to/emitter.service' 

class Foo { 
    EmitterService.get("some_id").subscribe(data => console.log("some_id channel: ", data)); 
    EmitterService.get("other_id").subscribe(data => console.log("other_id channel: ", data)); 
} 

// bar.component.ts 
import {EmitterService} from '../path/to/emitter.service' 

class Bar { 

    onClick() { 
    EmitterService.get("some_id").emit('you clicked!'); 
    } 
    onScroll() { 
    EmitterService.get("other_id").emit('you scrolled!'); 
    } 
} 

एक और उदाहरण: plunker

+0

यह बच्चे के लिए अच्छा है -> माता-पिता संचार। भाई के घटकों के बारे में क्या, यद्यपि? मान लीजिए कि foo बार का पैरेंट नहीं है, बल्कि इसके बजाय एक भाई घटक है। और जब आप foo में किसी तत्व पर क्लिक करते हैं, तो बार को अपडेट करने की आवश्यकता होती है।एक मास्टर-विस्तार परिदृश्य की तरह, लेकिन दोनों एक ही समय में पृष्ठ पर हैं (आईपैड स्प्लिटव्यू सोचें)। शायद यह अपना स्वयं का प्रश्न होना चाहिए, लेकिन मुझे कोणीय 2 में भाई घटक संचार के बारे में कोई जानकारी नहीं मिली है। –

+0

वाह यह पैटर्न अद्भुत है! मुझे मदद करने के लिए thx :) – jebbie

+0

सदस्यता समाप्त करने के लिए मत भूलना() '। –

संबंधित मुद्दे