wake-up-neo.com

Teilen Sie Daten zwischen Komponenten mithilfe eines Dienstes in Angular2

Ich entwickle eine Anwendung mit angle2. Ich habe ein Szenario, in dem ich komplexe Daten (Array von Objekten) von einer Komponente an eine andere Komponente übergeben muss (sie sind keine Eltern-Kind-Komponenten, sie sind zwei separate Komponenten), während sie routen (mit router.navigate ()). Ich habe das gegoogelt und die meisten Ergebnisse beschreiben das Szenario von Komponenten, die Eltern-Kind sind. Ich habe die Ergebnisse durchgesehen und diese Wege gefunden, die Daten weiterzugeben.

1) Shared Service erstellen 2) Als Routenparameter übergeben

Der zweite Ansatz funktioniert für mich (obwohl ich das nicht mag, wenn ich, wie oben erklärt, komplexe Daten habe). Ich kann die Daten nicht mithilfe des gemeinsam genutzten Dienstes freigeben. Meine Frage lautet: Funktioniert das Weitergeben von Daten zwischen Komponenten mithilfe von Diensten nur, wenn sich Komponenten in einer Eltern-Kind-Beziehung befinden? Lassen Sie mich auch wissen, ob es andere bevorzugte Möglichkeiten gibt, Daten zwischen einer Komponente und einer anderen Komponente zu übergeben.

Aktualisiert: Ich füge etwas Code aus meinem Szenario hinzu. Bitte teilen Sie mir meinen Fehler mit, warum die Weitergabe von Daten durch Shared Services nicht funktioniert.

Ich habe zwei Komponenten: 1) SearchComponent 2) TransferComponent .__ Ich setze die Daten in SearchComponent ein und möchte über UtilityService auf die Daten in TransferComponent zugreifen.

Dienstprogramm:

import {Injectable} from "@angular/core";

@Injectable()
export class UtilityService{
    constructor(){

    }
    public bioReagentObject = [];

    routeBioReagentObj(bioReagentObj){
        console.log("From UtilityService...", bioReagentObj);
        for (let each of bioReagentObj)
            this.bioReagentObject.Push(each)
        // console.log("From UtilityService",this.bioReagentObject);
    }

    returnObject(){
        console.log("From UtilityService",this.bioReagentObject);
        return this.bioReagentObject
    }



}

searchcomponent.ts

    import {UtilityService} from "../services/utilityservice.component";
    import {Component, OnInit, OnDestroy, Input} from '@angular/core';

@Component({
    selector: 'bioshoppe-search-details',
    providers: [UtilityService],
    templateUrl: 'app/search/searchdetails.component.html',
    styleUrls: ['../../css/style.css']
})

export class SearchDetailsComponent implements OnInit, OnDestroy {
    constructor(private route: ActivatedRoute,
                private utilityService: UtilityService,
                private router: Router) {

    }
    @Input() selected: Array<String> = [{barcode:123, description:"xyz"}];

       //This method is called from .html and this.selected has the data to be     shared.
       toTransfer() {
        this.utilityService.routeBioReagentObj(this.selected);
        this.router.navigate(['/transfer']);

    }
}

TransferService.ts

import {Component, Input, OnInit, OnDestroy} from '@angular/core';
import {TransferService} from "../services/transferservice.component";
import {UserService} from "../services/userservice.component";
import {SearchService} from "../services/searchservice.component";
import {ActivatedRoute} from '@angular/router';
import {UtilityService} from "../services/utilityservice.component";


@Component({
    selector: 'bioshoppe-transfer',
    providers: [TransferService, UserService, SearchService, UtilityService],
    templateUrl: 'app/transfer/transfer.component.html',
    styleUrls: ['../../css/style.css', '../../css/transfer.component.css']
})

export class TransferComponent implements OnInit, OnDestroy{
    constructor(private transferService: TransferService,
                private userService: UserService,
                private searchService: SearchService,
                private utilityService: UtilityService,
                private route: ActivatedRoute
    ) {

    }
ngOnInit() {
// I am trying to access the data here, but it print "undefind"
console.log("From Transferpage",this.utilityService.returnObject());
}
}

Ich bin sicher, dass etwas nicht stimmt, aber ich kann es einfach nicht herausfinden. Jede Hilfe wird geschätzt.

17
mrsan22

camaron hat recht. Dein Fehler ist, dass du zweimal UtilityService deklarierst:

  1. Einmal bei den Anbietern von SearchComponent.
  2. Einmal bei den Anbietern von TransferComponent.

Sie sollten den Dienst NUR EINMAL deklarieren, um sicherzustellen, dass beide Komponenten dieselbe Instanz erhalten. Dafür können Sie zwischen diesen beiden Optionen wählen:

  1. Deklarieren Sie den Dienst in den Providern eines @NgModule, dessen sowohl SearchComponent als auch TransferComponent in seinen Deklarationen hat. 9 mal von 10 ist dies die richtige Lösung!
  2. Deklarieren Sie den Dienst in den Providern eines @Component, der ein parent von sowohl SearchComponent als auch TransferComponent ist. Dies ist möglicherweise nicht machbar, je nachdem, wie Ihr Komponentenbaum aussieht.

Folgende Option # 1 endet mit:

@NgModule({
  imports: [CommonModule, ...],

  // Look, the components injecting the service are here:
  declarations: [SearchComponent, TransferComponent, ...],

  // Look, the service is declared here ONLY ONCE:
  providers: [UtilityService, ...]
})
export class SomeModule { }

Fügen Sie dann UtilityService in die Konstruktoren Ihrer Komponenten ein, ohne sie in den Anbietern der Komponenten zu reduzieren:

@Component({
  selector: 'foo',
  template: '...',
  providers: []  // DO NOT REDECLARE the service here
})
export class SearchComponent {
  constructor(private utilityService: UtilityService) { }
}

@Component({
  selector: 'bar',
  template: '...',
  providers: []  // DO NOT REDECLARE the service here
})
export class TransferComponent {
  constructor(private utilityService: UtilityService) { }
}
23
AngularChef

Sie müssen unterscheiden, wann der Dienst von NgModule stammt oder wann er von einer anderen Komponente stammt. 

Grundlagen

In Angular2 haben Sie eine hierarchische Struktur von Komponenten mit Eltern-Kind-Beziehung (wie Sie gesehen haben). Gleichzeitig werden alle Services mit Hilfe von Injektoren injiziert, die auch einen Hierarchiebaum (parallel zur Komponentenhierarchie) bilden. Der Baum der Injektoren stimmt nicht notwendigerweise mit dem Komponentenbaum überein, da aus Effizienzgründen Proxy-Injektoren vom übergeordneten Element vorhanden sein könnten. 

Wie es funktioniert

Die Aufgabe der Injektoren besteht darin, den im Konstruktor definierten Dienst in Ihre Komponente einzuspeisen, d. H. Zu finden, zu initiieren, falls nicht gefunden, und Ihnen zur Verfügung zu stellen. Wenn Sie in den Konstruktor einfügen, dass ein Dienst gewünscht wird, wird in den Injektorbaum von Ihrer Komponente bis zur Wurzel (das ist NgModule) für die Existenz des Dienstes gesucht. Wenn der Injektor feststellt, dass es einen definierten Anbieter für diesen Dienst gibt, aber keine Dienstinstanz, wird der Dienst erstellt. Wenn kein Anbieter weiter steigt.

Was Sie bisher gesehen haben 

Was Sie gesehen haben, ist, dass die übergeordnete Komponente den Dienst über "Anbieter" definiert, und Injektoren, die nach dem Dienst suchen, einen Sprung in der Baumstruktur finden, den Anbieter finden, den Dienst initiieren und Ihrer untergeordneten Komponente geben. Damit alle Komponenten eines Teilbaums denselben Dienst haben, müssen Sie den Anbieter nur im gemeinsamen Stamm des Teilbaums definieren. Wenn Sie denselben Service für das gesamte Modul benötigen, müssen Sie diesen Service in Modulanbietern definieren. Dies ist der sogenannte Singleton - Dienst.

Einige extra

Normalerweise, wenn Sie den Service injizieren möchten und ihn bis zum Root-Pfad nicht finden konnten, werden Fehler während der Kompilierung/Laufzeit angezeigt. Wenn Sie jedoch definieren, dass Sie den Optional - Dienst einspeisen möchten, schlägt der Injektor nicht fehl, wenn der Anbieter für diesen Dienst nicht gefunden wird.

Mehr oder weniger...

Einige nützliche Links:

  1. https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html

  2. https://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html

3
laser

Sie können dies erreichen, indem Sie mithilfe von Observables Daten zwischen zwei Komponenten austauschen.

Ich habe diesen Beitrag nicht geschrieben, aber er ist sehr nützlich und leicht zu verstehen - 

Ein kurzer Beitrag, um ein Beispiel für etwas zu zeigen, durch das ich für kurze Zeit stecken blieb - wie man in Angular 2/4 zwischen Komponenten kommuniziert.

Die Lösung ist, ein Observable und ein Subject zu verwenden (was eine Art Observable ist)

http://jasonwatmore.com/post/2016/12/01/angular-2-communicating-between-components-with-observable-subject

0
Aamol