Mon application a un NameService qui contient le nom.
Deux composants enfants, App, Navbar et TheContent, font référence à ce service. Chaque fois que le nom change dans le service, je souhaite qu'il soit mis à jour dans les deux autres composants. Comment puis-je faire ceci?
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) {
}
}
Fournissez un événement dans le service et abonnez-vous à celui-ci dans les composants:
@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();
}
}
Voir également
angular.io - INTERACTION COMPOSANTE - Le parent et les enfants communiquent via un service
Comme name
dans NameService
est un type primitif, vous obtiendrez une instance différente dans le service et vos composants. Lorsque vous modifiez name
dans NameService
, les propriétés du composant ont toujours la valeur initiale et la liaison ne fonctionne pas comme prévu.
Vous devez appliquer ici la "règle du point" angular1 et vous lier à un type de référence. Modifiez NameService
pour stocker un objet contenant le nom.
export interface Info {
name:string;
}
@Injectable()
class NameService {
info: Info = { name : "Jack" };
change(){
this.info.name = "Jane";
}
}
Vous pouvez vous lier à cet objet et obtenir automatiquement les mises à jour de la propriété 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;
}
}
Je pense que la solution fournie par Günter est la meilleure.
Cela dit, vous devez savoir que les services Angular2 sont des singleton qui ont lieu dans un arbre d’injecteurs. Cela signifie que:
bootstrap
], l'instance peut être partagée par tous les éléments (composants et service).providers
), l'instance sera spécifique au composant et à ses sous-composants.Pour plus de détails sur cet aspect, vous pouvez consulter le document "Injection de dépendance hiérarchique": https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html =
J'espère que ça vous aide, Thierry