2016-10-28 4 views
5

Ich versuche einen DataResolver Dienst zu schreiben, der es dem Angular 2 Router ermöglicht, Daten vor der Initialisierung meiner Komponente vorzuladen.Angular 2: einen Wert an die Routendaten übergeben resolve

Der Resolver muss verschiedene API-Endpunkte aufrufen, um Daten für die zu ladende Route abzurufen. Anstatt einen Resolver für jede meiner vielen Komponenten zu haben, erstelle ich einen generischen Resolver. Daher möchte ich benutzerdefinierte Eingaben in der Routendefinition übergeben, die auf den richtigen Endpunkt verweisen. Betrachten wir zum Beispiel diese Routen:

app.routes.ts

appRoutes = [ 
    { 
    path: 'project/:id', 
    component: ProjectComponent, 
    resolve: { data: DataResolver } 
    }, 
    { 
    path: 'store/:id', 
    component: StoreComponent, 
    resolve: { data: DataResolver } 
    } 
] 

Im ersten Fall müssen die Resolver /path/to/resource1/id nennen. Im zweiten Fall /path/to/resource2/id. Idealerweise würde ich den Endpunkt als Argument in der Routendefinition übergeben, die dann im Konstruktor DataResolver verfügbar wäre.

Kann dies mit einer generischen Resolver-Klasse durchgeführt werden?

Angular 2.0.1 in Typescript 2.0.3

Antwort

10

geschrieben Ich weiß nicht, über sie im Konstruktor verfügbar machen, ohne DI zu verwenden. Aber wenn man es in der resolve Methode zur Verfügung möchten, können Sie nur eine data Eigenschaft in der Routendefinition hinzufügen, und dies würde es dem Diese Antwort mein Problem gelöst ActivatedRouteSnapshot

{ 
    path: 'project/:id', 
    component: ProjectComponent, 
    resolve: { data: DataResolver }, 
    data: { path: 'project/:id' } 
} 

class DataResolve implements Resolve<string> { 
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { 
    return route.data['path']; 
    } 
} 
+0

in der letzten Zeile - 'route.data ['path']', wird ': id' automatisch durch den aktuellen route-Parameter ersetzt oder ist es der Literal-String' project /: id'? – BeetleJuice

+1

Nein. Ich denke, ich habe deine Frage missverstanden. Ich dachte, dass du das wolltest. Holen Sie sich die "URL" von der "Route". Es wird ein 'UrlSegment []' sein. 'url [1] .path' sollte die ID haben und' url [0] .path' sollte 'project' sein. –

+0

Ich hätte es besser machen können, das zu erklären. 'resolve()' ruft die API auf und gibt das Observable zurück, das die vom Server zurückgegebenen Daten ausgibt. Meine Herausforderung bestand darin, dass der aufzurufende API-Endpunkt von der Komponente abhängt, deren Daten aufgelöst werden. Ihre Antwort ist jedoch hilfreich. Ich kann die Eigenschaft 'data' der Route verwenden, um benutzerdefinierte Eingaben für' resolve() 'verfügbar zu machen. Vielen Dank. – BeetleJuice

0

verfügbar machen, aber ich habe auch dies erforderlich angewendet werden, wenn die Route mehrere Resolver hat.

z.

{ 
    path: 'transactions/showcase/edit/:id', 
    component: ClientsTransactionsFormComponent, 
    resolve: { 
     clients: Resolver, 
     clientTransaction: Resolver, 
     clientTransactionTypes: Resolver 
    }, 

In diesem Fall habe ich mein Problem gelöst, indem Sie ein Array in Daten übergeben.

data: ['Clients/GetAll', 'ClientTransactions/GetByID/', 'ClientTransactionTypes/GetAll'] 

und modifiziert auch mein Resolver wie folgt ..

resolve(route: ActivatedRouteSnapshot) { 
    let row = []; 
    let id = ""; 

    Object.keys(route.data).forEach(e => { 
     row.push(route.data[e]); 
    }) 

    let path: string = row[0]; 
    delete row[0]; 

    route.data = row; 

    if (path.lastIndexOf('/') == path.length - 1) { 
     id = route.params['id']; 
    } 

    return this._httpService.httpGet(this.baseUrl + path + id); 
    } 

hoffen, dass es jemand hilft.

Verwandte Themen