2016-03-27 5 views
6

Sieht aus wie Shared Services ist die beste Praxis, um viele Situationen zu lösen, wie die Kommunikation zwischen Komponenten oder als Ersatz der alten $ Rootscope-Konzept von eckigen 1. Ich versuche, meine zu schaffen, aber es ist nicht Arbeiten. Irgendeine Hilfe ? ty !!!Angular 2 - Shared Service verwenden

app.component.ts

import {Component} from 'angular2/core'; 
import {OtherComponent} from './other.component'; 
import {SharedService} from './services/shared.service'; 
@Component({ 
selector: 'my-app', 
providers: [SharedService], 
directives: [OtherComponent], 
template: ` 
    <button (click)="setSharedValue()">Add value to Shared Service</button> 
    <br><br> 
    <other></other> 
` 
}) 
export class AppComponent { 
data: string = 'Testing data'; 
setSharedValue(){ 
    this._sharedService.insertData(this.data); 
    this.data = ''; 
    console.log('Data sent'); 
} 
constructor(private _sharedService: SharedService){} 
} 

other.component.ts

import {Component, OnInit} from "angular2/core"; 
import {SharedService} from './services/shared.service'; 
@Component({ 
selector : "other", 
providers : [SharedService], 
template : ` 
I'm the other component. The shared data is: {{data}} 
`, 
}) 
export class OtherComponent implements OnInit{ 
data: string[] = []; 
constructor(private _sharedService: SharedService){} 
ngOnInit():any { 
    this.data = this._sharedService.dataArray; 
} 
} 

Antwort

7

Die meisten der Zeit, müssen Sie Ihre Shared-Service definieren, wenn Ihre Anwendung Bootstrapping:

bootstrap(AppComponent, [ SharedService ]); 

und nicht erneut innerhalb des providers Attributs Ihrer Komponenten definieren. Auf diese Weise haben Sie eine einzige Instanz des Dienstes für die gesamte Anwendung.


In Ihrem Fall, da OtherComponent ist eine Unterkomponente des AppComponent ein, entfernen Sie einfach das providers Attribut wie folgt aus:

@Component({ 
    selector : "other", 
    // providers : [SharedService], <---- 
    template : ` 
    I'm the other component. The shared data is: {{data}} 
    `, 
}) 
export class OtherComponent implements OnInit{ 
    (...) 
} 

diese Weise können sie für beide die gleiche Instanz des Dienstes geteilt wird Komponenten. OtherComponent wird den aus der übergeordneten Komponente (AppComponent) verwenden.

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

+1

Sie sind zu schnell: P Hier ist ein funktionierender Plünderer: https://plnr.rc/edit/HX3LT9RaJD6ki3vpa1aW. Da die Daten in einem Array gespeichert werden, müssen Sie auch über das Array iterieren, um die separaten Informationen anzuzeigen, die Sie speichern. –

+1

Korrigieren Sie mich, wenn ich falsch liege, aber es sieht so aus, als hätte sich der Bootstrap in Angular 2 final geändert. Wissen Sie, wie ich die von Ihnen bereitgestellte Lösung anpassen kann? Vielen Dank! – guicl

+0

Tatsächlich scheint diese gelieferte Lösung nicht auf der neuesten Version von Angular 5 zu funktionieren. Die Bootstrap-Syntax wurde ebenfalls geändert, wenn Sie versuchen, dass sie sagt: "Dienst kann nicht als Eintragskomponente verwendet werden" –

3

Sie benötigen einen globalen Anbieter in Ihrem Modul hinzufügen möchte, dann brauchen Sie nicht, diesen Anbieter in jeder Komponente hinzuzufügen. versuchen, diese

app.module.ts

@NgModule({ 
    imports: [BrowserModule, FormsModule, HttpModule], 
    declarations: [AppComponent, LoginComponent, InComponent], 
    providers: [LoginService], 
    bootstrap: [AppComponent] 
}) 

app.component.ts

@Component({ 
    moduleId: module.id, 
    selector: 'app', 
    templateUrl: './app.component.html' 
}) 
export class AppComponent { 
    constructor(public loginService: LoginService) { 

    } 
} 

login.component.ts

@Component({ 
    moduleId: module.id, 
    selector: 'login', 
    templateUrl: './login.component.html' 
}) 
export class LoginComponent { 

    constructor(public loginService: LoginService) { 

    } 
} 

ich für Sie diese Arbeit hoffen.