2016-02-08 9 views
20

Ich habe ein Objekt, das ich zwischen meinen Komponenten in einer Angular2 App teilen möchte. HierAngular2 - Teilen von Daten zwischen Komponenten mit Diensten

ist die Quelle der ersten Komponente:

/* app.component.ts */ 

// ...imports 
import {ConfigService} from './config.service'; 

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/templates/app.html', 
    directives: [Grid], 
    providers: [ConfigService] 
}) 
export class AppComponent { 
    public size: number; 
    public square: number; 

    constructor(_configService: ConfigService) { 
     this.size = 16; 
     this.square = Math.sqrt(this.size); 

     // Here I call the service to put my data 
     _configService.setOption('size', this.size); 
     _configService.setOption('square', this.square); 
    } 
} 

und die zweite Komponente:

/* grid.component.ts */ 

// ...imports 
import {ConfigService} from './config.service'; 

@Component({ 
    selector: 'grid', 
    templateUrl: 'app/templates/grid.html', 
    providers: [ConfigService] 
}) 
export class Grid { 
    public config; 
    public header = []; 

    constructor(_configService: ConfigService) { 
     // issue is here, the _configService.getConfig() get an empty object 
     // but I had filled it just before 
     this.config = _configService.getConfig(); 
    } 
    } 

und schließlich mein kleiner Service, die ConfigService:

/* config.service.ts */ 

import {Injectable} from 'angular2/core'; 

@Injectable() 
export class ConfigService { 

    private config = {}; 

    setOption(option, value) { 
     this.config[option] = value; 
    } 

    getConfig() { 
     return this.config; 
    } 
} 

Meine Daten werden nicht geteilt, in der grid.component.ts gibt die _configService.getConfig() Zeile ein leeres Objekt zurück, bu t es ist gerade zuvor in der app.component.ts gefüllt.

Ich las die Dokumente und Tutorials, nichts hat funktioniert.

Was fehlt mir?

Dank

GELÖST

Mein Problem war, dass ich zweimal mein ConfigService wurde injiziert wird. Im Bootstrap der Anwendung und in der Datei, in der ich sie verwende.

Ich habe die providers Einstellung entfernt und es hat funktioniert!

+0

Als eine Nebenbemerkung, ziehen Sie in Betracht, die Serviceaufrufe aus dem Konstruktor zu verschieben. – Stanislasdrg

+0

http://www.angulartutorial.net/2017/09/angular-share-data-between-components.html – Prashobh

Antwort

22

Sie definieren es innerhalb Ihrer zwei Komponenten. Daher wird der Dienst nicht geteilt. Sie haben eine Instanz für die Komponente AppComponent und eine weitere für die Komponente Grid.

@Component({ 
    selector: 'my-app', 
    templateUrl: 'app/templates/app.html', 
    directives: [Grid], 
    providers: [ConfigService] 
}) 
export class AppComponent { 
    (...) 
} 

Die schnelle Lösung ist es, das providers Attribut auf Ihre Grid-Komponente ... Auf diese Weise der Dienstinstanz durch die AppComponent und seine Kinder Komponenten gemeinsam genutzt werden zu entfernen. Die andere Lösung besteht darin, den entsprechenden Provider innerhalb der bootstrap-Funktion zu registrieren. In diesem Fall wird die Instanz von der gesamten Anwendung geteilt.

bootstrap(AppComponent, [ ConfigService ]); 

Um zu verstehen, warum Sie tun müssen, dass Sie sich der „hierarchischen Injektoren“ -Funktion von Angular2 sein müssen. Folgende Links könnten nützlich sein:

+0

OK, tatsächlich habe ich beide ... Im Bootstrap und in Providern in jeder Datei möchte ich. Das kann mein Problem sein. Ich teste es so schnell wie möglich und sage Ihnen, ob das das Problem war. – keversc

+0

Ja, aber Sie brauchen das nicht. Wenn Sie Ihre Provider konfigurieren, ist der Bereich der zugeordneten Instanz das Element und seine Unterelemente. Durch erneutes Definieren wird eine neue Instanz erstellt. Wenn Sie beispielsweise Ihren Provider im Bootstrap und einen in einer Komponente definieren, haben Sie zwei Instanzen des Service: einen auf der Anwendungsebene und einen auf der Komponentenebene. –

+0

Wenn Sie nur auf der Anwendungsebene definieren, können alle Komponenten diese Instanz durch die Abhängigkeitsinjektion verwenden. Das liegt daran, dass der Injektor der Komponente ein Sub-Injektor oder der Anwendungsinjektor ist. Sie nutzen die prototypische Vererbung. Das Kind kann Elemente in der Eltern sehen –

4

nicht ConfigService zu providers Ihrer Komponente hinzufügen Sie. Dies führt zu neuen Instanzen für jede Komponente. Fügen Sie es zu providers einer gemeinsamen übergeordneten Komponente hinzu. Wenn Sie es zu Ihrer Root-Komponente hinzufügen oder bootstrap(App, [ConfigService]), teilt Ihre gesamte Anwendung eine einzige Instanz.

+0

OK danke, ich werde dies betrachten, für jetzt habe ich die ConfigService sowohl im Bootstrap und der Datei, das kann mein Problem sein. Ich versuche das so schnell wie möglich – keversc

5

Wenn Sie den Dienst für die neueste Version von eckig freigeben möchten, können Sie ihn nicht zur Bootstrap-Funktion hinzufügen. Fügen Sie es einfach wie bei einem normalen Dienst der NgModule-Anbieterliste hinzu. Das Standardverhalten ist Singleton.

bootstrap (AppComponent);

@NgModule({ 
    declarations: [ 
     .... 
    ], 
    imports: [ 
     ....  
    ], 
    providers: [ 
     ConfigService, 
.... 
Verwandte Themen