2016-01-11 17 views
52

के साथ किसी सेवा से घटकों में परिवर्तनीय परिवर्तनों को अद्यतन करना मेरे ऐप में नाम सेवा है जिसका नाम है।कोणीय 2

ऐप, नवबार और द कॉन्टेंट के दो बच्चे घटक हैं जो इस सेवा का संदर्भ देते हैं। जब भी सेवा में नाम बदलता है, मैं चाहता हूं कि यह दोनों अन्य घटकों में अपडेट हो। मैं यह कैसे कर सकता हूँ?

import {Component, Injectable} from 'angular2/core' 

// Name Service 

@Injectable() 
class NameService { 
    name: any; 
    constructor() { 
    this.name = "Jack"; 
    } 
    change(){ 
    this.name = "Jane"; 
    } 
} 

// The navbar 
@Component({ 
    selector: 'navbar', 
    template: '<div>This is the navbar, user name is {{name}}.</div>' 
}) 
export class Navbar { 
    name: any; 
    constructor(nameService: NameService) { 
    this.name = nameService.name; 
    } 
} 

// The content area 
@Component({ 
    selector: 'thecontent', 
    template: '<div>This is the content area. Hello user {{name}}. <button (click)=changeMyName()>Change the name</button></div>' 
}) 
export class TheContent { 

    name: any; 

    constructor(public nameService: NameService) { 
    this.name = nameService.name; 
    } 
    changeMyName() { 
     this.nameService.change(); 
    console.log(this.nameService.name); 
    } 
} 


@Component({ 
    selector: 'app', 
    providers: [NameService], 
    directives: [TheContent, Navbar], 
    template: '<navbar></navbar><thecontent></thecontent>' 
}) 
export class App { 
    constructor(public nameService: NameService) { 
    } 
} 

उत्तर

67

सेवा में एक घटना प्रदान करें और घटकों में सदस्यता ले:

@Injectable() 
class NameService { 
    name: any; 
    // EventEmitter should not be used this way - only for `@Output()`s 
    //nameChange: EventEmitter<string> = new EventEmitter<string>(); 
    nameChange: Subject<string> = new Subject<string>(); 
    constructor() { 
    this.name = "Jack"; 
    } 
    change(){ 
    this.name = 'Jane'; 
    this.nameChange.next(this.name); 
    } 
} 
export class SomeComponent { 
    constructor(private nameService: NameService) { 
    this.name = nameService.name; 
    this._subscription = nameService.nameChange.subscribe((value) => { 
     this.name = value; 
    }); 
    } 

    ngOnDestroy() { 
    //prevent memory leak when component destroyed 
    this._subscription.unsubscribe(); 
    } 
} 

भी देखें
angular.io - COMPONENT INTERACTION - Parent and children communicate via a service

+1

इसके अलावा में घटना से सदस्यता समाप्त करने के लिए याद घटक घटक, घटक उदाहरण जारी नहीं किया जाएगा। सब्सक्राइब फ़ंक्शन द्वारा लौटाई गई ऑब्जेक्ट पर सदस्यता रद्द करने की आवश्यकता है। – Chandermani

+0

@ कंधर्मनी क्या आप इस बारे में संकेत दे सकते हैं कि टीएस में यह कैसे किया जाता है? –

+3

'सदस्यता लें = nameService.nameChange.subscribe ((मान) => {this.name = value;}); subscription.unsubscribe() '। मुझे इस मुद्दे का सामना करना पड़ा इसलिए अस्वीकरण। यदि सदस्यता को अन्य विधि से रद्द करना है, तो परिवर्तनीय वर्ग स्तर – Chandermani

19

में name के बाद से 10 एक प्राचीन प्रकार है, आपको सेवा और आपके घटकों में अलग-अलग उदाहरण मिलेंगे। जब आप name को NameService में बदलते हैं, तो घटक गुणों में अभी भी प्रारंभिक मान होता है और बाध्यकारी अपेक्षा के अनुसार काम नहीं करता है।

आपको यहां कोणीय 1 "डॉट नियम" लागू करना चाहिए और संदर्भ प्रकार से जुड़ना चाहिए। नाम रखने वाले ऑब्जेक्ट को स्टोर करने के लिए NameService बदलें।

export interface Info { 
    name:string; 
} 

@Injectable() 
class NameService { 
    info: Info = { name : "Jack" }; 
    change(){ 
    this.info.name = "Jane"; 
    } 
} 

आप इस वस्तु के लिए बाध्य है और स्वचालित रूप name संपत्ति को अपडेट प्राप्त कर सकते हैं।

// The navbar 
@Component({ 
    selector: 'navbar', 
    template: '<div>This is the navbar, user name is {{info.name}}.</div>' 
}) 
export class Navbar { 
    info: Info; 
    constructor(nameService: NameService) { 
    this.info = nameService.info; 
    } 
} 
+0

इस तरह मैं इसे भी करूँगा। कोणीय 1 में "हमेशा अपने मॉडल में एक बिंदु है" आपके बाइंडिंग को सिंक करने के प्रयास को कम करने का एक अच्छा तरीका है, यह उपयोग के मामले के आधार पर Angular2 में भी उपयुक्त हो सकता है। इसके बिना, मॉडल सिंक करने के लिए इवेंट एमिटर का उपयोग करके थकाऊ हो सकता है। – pixelbits

+0

वाह, यह कार्य EventEmitter तरीके से तुलना क्यों करता है? यह बहुत कम काम की तरह लगता है? –

+0

क्या यह नवरबार दृश्य अपडेट करता है? कृपया यहां देखें [plnkr] (http://plnkr.co/edit/G4TwpyQs9QuIPB68XyCQ?p=preview)। एक बार जब आप बटन पर क्लिक करेंगे तो यह navbar व्यू को कैसे अपडेट करेगा? – micronyks

11

मुझे लगता है कि गुंटर द्वारा प्रदान किया गया समाधान सबसे अच्छा है।

उस ने कहा, आपको अवगत होना चाहिए कि कोणीय 2 सेवाएं सिंगलटन हैं जो इंजेक्टरों के पेड़ में होती हैं। इसका मतलब है कि:

  • यदि आप अनुप्रयोग स्तर (bootstrap विधि का दूसरा पैरामीटर के भीतर) पर आपकी सेवा को परिभाषित, उदाहरण के सभी तत्वों (घटकों और सेवा) द्वारा शेयर हो सकता है।
  • यदि आप घटक स्तर पर अपनी सेवा को परिभाषित करते हैं (providers विशेषता के भीतर), उदाहरण घटक और उसके उप घटकों के लिए विशिष्ट होगा।

ऐसे पहलू की अधिक जानकारी के लिए, यदि आप "श्रेणीबद्ध निर्भरता इंजेक्शन" डॉक पर एक नजर है कर सकते हैं: https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

आशा है कि यह आप में मदद करता है, थियरी