2016-10-21 5 views
0

So jetzt habe ich eine Anwendung, die nach oben wie folgt festgelegt ist:Erstellen von Daten verfügbar zu mehreren Modulen

AppModule 
    SubModule 
     Multiple Components 
    SecondSubModule 
     Multiple Components 

Ich brauche einen Datenanruf zu einem REST-API in die Lage zu machen, die in beide eingespeist werden SubModule und SecondSubModule. Ich habe überlegt, ein Modul zu erstellen, um beide zu verbinden und die Daten dort anzurufen, aber ich kann nicht herausfinden, wie man einen Datenanruf in einem Modul durchführt oder ob ich es überhaupt tun sollte.

Und wenn ich eine Komponente mache, erfordert es, dass es zu der Markup als ein leeres Tag irgendwo hinzugefügt wird, die bestenfalls hacky ist.

Grundsätzlich würde Ich mag diese „verpackt“ unter einem anderen Modul, das die notwendigen Daten Anruf tätigt und speist sie in den beiden anderen Modulen wie folgt aus:

AppModule 
    ParentModule 
     SubModule 
      Multiple Components 
     SecondSubModule 
      Multiple Components 

Das Ziel hier ist das gesamte Paket machen transportierbar und vollständig getrennt von der AppModule, so dass es zu jeder anderen App hinzugefügt werden kann, indem einfach die zugehörigen Dateien hinzugefügt und zu AppModule hinzugefügt werden.

Was ist die korrekte Vorgehensweise in Angular 2?

Antwort

2

Die Antwort hier für irgendjemand anderen, der über dieses kommt, ist dieses.

Diese Art zu denken ist sehr eckig 1, wo in Sie Daten an einen Controller liefern würde, und durch Vererbung weitergeben.

Während es Vererbung durch die Verwendung von @Input Dekoratoren gibt, ist die wirkliche Lösung hier, einen Datendienst zu erstellen, der die Arbeit für Sie erledigt.

Die Werkzeuge sind Sie benötigen:

  • injizierbare Headers
  • Http
  • beobachtbare
  • rxjs/beobachtbare/von
  • rxjs/beobachtbare/share
  • rxjs/beobachtbare/Karte

In Ihren Datendienst, werden Sie die Abhängigkeiten importieren:

// App Imports 
import { Injectable } from '@angular/core'; 
import { Headers, Http } from "@angular/http"; 
import {Observable} from 'rxjs/Observable'; 

// RXJS Imports 
import 'rxjs/observable/of'; 
import 'rxjs/add/operator/share'; 
import 'rxjs/add/operator/map'; 

Dann brauchen Sie ein injizierbares Dekorateur

@Injectable 

Sie Ihre Klasse

export class DataService { 

Weiter Dann brauchen kommt der Konstruktor

// Constructor 
constructor(private http: Http) { } 

Jetzt müssen wir einige Variablen

// Variables 
private data: any = null; 
private observable: Observable<any>; 
private headers = new Headers({"Content-Type": "application/json"}); 

data werden unsere Daten halten, sobald es von der REST/JSON API abgerufen wurde

observable unsere beobachtbaren halten, das Objekt zu denen externe Anrufe abonnieren (das ist der magische Teil)

headers hält einfach die Überschriften, die wir verwenden werden, um die HTTP-Anfrage zu senden.

Jetzt müssen wir die Funktion definieren, die Daten

// Returns data 
getData() { 

Jetzt erhalten wird, einen Algorithmus kommen, um die richtige Objekt zurück auf den Zustand des Dienstes abhängig.

// If we already have data 
if (this.data){ 

    // Return the data 
    return Observable.of(this.data); 

} else if (this.observable){ 

    // Otherwise if we have an observable, return it 
    return this.observable; 
} else { 

    // Otherwise get the data 
    this.observable = this.http.get("/api/myApiClass", {headers: this.headers}) 
    .map(response => { 

     // Clear the observable 
     this.observable = null; 

     // If the call failed 
     if (response.status == 400) { 

      // Return false 
      return false 
     } else if (response.status == 200){ 

      // Otherwise set the data 
      this.data = response.json().data; 

      // And return the response 
      return this.data 
     } 
    }) 
    .share(); 

    // Return the observable to be subscribed to 
    return this.observable; 
} 

Beachten Sie die .share() in unmittelbarer Nähe der dort Ende. Das ist der letzte Teil der Magie, der dafür sorgt, dass wir nur einen HTTP-Aufruf machen.

Jetzt müssen wir diesen Dienst in dem Modul bereitstellen, das die Komponenten enthält, die diesen Dienst verwenden.

Zunächst importieren Sie die Datendienst in Ihrem Modul

import { DataService } from "../../services/data.service"; 

jetzt erklären Sie es in Ihrem Anbieter

providers: [ DataService ] 

Nun werden alle Unterkomponenten Zugriff auf den Dienst als Singleton haben.

nun in den Komponenten, die diesen Datendienst anrufen, werden Sie den Service dafür, dass schließen OnInit importieren:

import {Component,OnInit} from '@angular/core'; 
import { DataService } from "../services/data.service"; 

Und den Datendienst in Ihrem Konstruktor

constructor(private dataService: DataService){}; 

Nun endlich definieren , abonnieren Sie die Observable, die im Datendienst enthalten ist:

Am Ende Ihrer Dateien sollten wie folgt aussehen:

data.service.ts

// App Imports 
import { Injectable } from '@angular/core'; 
import { Headers, Http } from "@angular/http"; 
import {Observable} from 'rxjs/Observable'; 

// RXJS Imports 
import 'rxjs/observable/of'; 
import 'rxjs/add/operator/share'; 
import 'rxjs/add/operator/map'; 

@Injectable() 
export class DataService{ 

    // Constructor 
    constructor(private http: Http) { } 

    // Variables 
    private data: any = null; 
    private observable: Observable<any>; 
    private headers = new Headers({"Content-Type": "application/json"}); 

    // Returns data 
    getData() { 

     // If we already have data 
     if (this.data){ 

      // Return the data 
      return Observable.of(this.data); 

     } else if (this.observable){ 

      // Otherwise if we have an observable, return it 
      return this.observable; 
     } else { 

      // Otherwise get the data 
      this.observable = this.http.get("/api/myApiClass", {headers: this.headers}) 
      .map(response => { 

       // Clear the observable 
       this.observable = null; 

       // If the call failed 
       if (response.status == 400) { 
        // Return false 
        return false 
       } else if (response.status == 200){ 
        // Otherwise set the data 
        this.data = response.json().data; 

        // And return the response 
        return this.data 
       } 
      }) 
      .share(); 


      // Return the observable to be subscribed to 
      return this.observable; 
     } 
    } 
} 

my.module.ts

import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 

import { DataService } from "../../services/data.service"; 

@NgModule({ 
    imports: [ 
     CommonModule 
    ], 
    declarations: [], 
    exports: [], 
    providers: [ DataService ] 
}) 

export class MyModule { 

} 

my.component.ts

import {Component,OnInit} from '@angular/core'; 
import { DataService } from "../services/data.service"; 

@Component({ 
    selector: 'my-selector', 
    template: require('./my.component.html') 
}) 

export class MyComponent{ 

    constructor(private dataService: DataService){}; 

    data: any; 

    ngOnInit(){ 
     this.dataService.getData().subscribe(data => { 
      this.data= data; 
     }); 
    } 
} 

Ich weiß, dass dies ein wenig langatmig ist, aber es sollte für jeden da draußen hilfreich sein, der das Gleiche machen möchte.

Verwandte Themen