2016-03-27 6 views
0

Ich möchte Daten zwischen den Komponenten teilen, also im implementiert einen Service, der einen EventEmitter hat.Angular 2 ES6/7 EvenTemitter Update andere Komponente

Mein Service sieht wie folgt aus:

@Injectable() 
export class LanguageService { 



    constructor() { 
    this.languageEventEmitter = new EventEmitter(); 
    this.languages = []; 

    this.setLanguages(); 
    } 

    setLanguages() { 

    var self = this; 

    axios.get('/api/' + api.version + '/' + api.language) 
     .then(function (response) { 
     _.each(response.data, function (language) { 
      language.selected = false; 
      self.languages.push(language); 
     }); 
     self.languageEventEmitter.emit(self.languages); 
     }) 
     .catch(function (response) { 
     }); 
    } 

    getLanguages() { 
    return this.languages; 
    } 

    toggleSelection(language) { 
    var self = this; 
    language.selected = !language.selected; 
    self.languages.push(language); 
    self.languageEventEmitter.emit(self.languages); 
    } 

} 

I Komponenten haben, die wie folgt auf den Dienst abonniert haben:

self.languageService.languageEventEmitter.subscribe((newLanguages) => { 
    _.each(newLanguages, function (language) { 
    self.updateLanguages(language); 
    }); 
}); 

Wenn beide Komponenten geladen werden, erhalten die Sprache Arrays gefüllt, wie ich wünsche.

Dies ist die erste Komponente:

export class LanguageComponent { 

    static get parameters() { 
    return [[LanguageService]]; 
    } 

constructor(languageService) { 
    var self = this; 

    this.languageService = languageService; 
    this.languages = []; 

    this.setLanguages(); 
} 

setLanguages() { 

    var self = this; 

    self.languageService.languageEventEmitter.subscribe((newLanguages) => { 
    _.each(newLanguages, function (language) { 
     self.updateLanguages(language); 
    }) 
    }); 

} 

updateLanguages(newLanguage) { 
    var self = this; 

    if (!newLanguage) { 
    return; 
    } 

    var match = _.find(self.languages, function (language) { 
    return newLanguage._id === language._id; 
    }); 

    if (!match) { 
    self.languages.push(newLanguage); 
    } 

    else { 
    _.forOwn(newLanguage, function (value, key) { 
     match[key] = value; 
    }) 
    } 

    toggleLanguageSelection(language) { 
    var self = this; 
    self.languageService.toggleSelection(language) 
    } 

} 

Wenn LanguageComponent die Funktion toggleLanguageSelection ausführt(), die durch einen Klick Ereignis ausgelöst, die andere Komponente, die wie folgt abonniert:

self.languageService.languageEventEmitter.subscribe((newLanguages) => { 
    _.each(newLanguages, function (language) { 
    self.updateLanguages(language); 
    }) 
}); 

doesn‘ Ich werde nicht von der Veränderung erfahren. Ich denke, das passiert, weil beide Komponenten eine andere Instanz meines LanguageService bekommen, aber da bin ich mir nicht sicher. Ich habe auch versucht ein Singleton zu erstellen, aber angular'2 di funktioniert dann nicht mehr. Was ist der Grund für dieses Problem und wie kann ich das lösen?

+1

Bitte verwenden Sie keine [EventEmitter auf Dienste] (http://stackoverflow.com/questions/36076700/what-is-the-proper -use-of-a-eventemitter). –

Antwort

1

Sie benötigen eine Shared-Service zu definieren, wenn Ihre Anwendung Bootstrapping:

bootstrap(AppComponent, [ SharedService ]); 

und nicht erneut im providers Attribute Ihrer Komponenten definieren. Auf diese Weise haben Sie eine einzige Instanz des Dienstes für die gesamte Anwendung. Komponenten können es nutzen, um miteinander zu kommunizieren.

Dies liegt an der Funktion "hierarchische Injektoren" von Angular2. Weitere Einzelheiten finden Sie diese Frage: