2016-05-24 8 views
5

Używanie Angular 2 rc.1 i TypeScript. Mam dużo problemów z przekazywaniem parametrów routingu do mojego komponentu, gdy komponent jest załadowany do podprogramu. Używam pakietu @angular/router-deprecated.Angular 2: Jak przekazać parametry trasy do podprogramu?

W moim głównego składnika, mam skonfigurowane trasy jako takie:

@RouteConfig([ 
    {path:'/top', name:'Top', component: EndPointComponent}, 
    {path:'/sub/...', name:'Sub', component: MiddleManComponent} 
]) 

Oto komponent końcowym gdzie próbuję odczytać parametry

import {Component} from '@angular/core'; 
import {RouteParams} from '@angular/router-deprecated'; 
@Component({ 
    template: 'Route Params: {{routeParams.params | json}}' 
}) 
export class EndPointComponent{ 
    constructor(private routeParams:RouteParams){} 
} 

Oto komponent middleman z podprogramem do EndPointComponent

import {Component} from '@angular/core'; 
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated'; 
import {EndPointComponent} from "./endpoint.component"; 

@Component({ 
    directives: [ROUTER_DIRECTIVES] 
    template: `<router-outlet></router-outlet>` 
}) 
@RouteConfig([ 
    {path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true} 
]) 
export class MiddleManComponent {} 

Parametry mogą być z powodzeniem czytać z routeParams przedmiotu EndPointComponent gdy składnik jest ładowany z trasy najwyższego poziomu (np: trasa o nazwie „top” w składniku głównym). Jednak parametry są zawsze puste, gdy przechodzę do EndPointComponent przechodząc przez MiddleManComponent (np .: przez trasę o nazwie "Sub" w komponencie root).

Czy routery dziecięce wyszukują parametry przed rodzicami, zanim rozwiązują trasy? To nie ma większego sensu, więc założę się, że czegoś brakuje. Moje pytanie brzmi po prostu: jak przekazać parametry trasy do podprogramu?

PS: Próbowałem zbudować plunarem na demo this setup, ale poddałem się, gdy nie mogłem ustalić, dlaczego aplikacja się nie wczytuje.

Odpowiedz

4

Trasy dla dzieci w rzeczywistości otrzymują własne wystąpienie RouteParams, inne niż trasy nadrzędne. Ma to na celu uniknięcie nazwania kolizji i ułatwienie enkapsulacji przekierowanego komponentu.

Jednym ze sposobów udostępniania parametrów trasy nadrzędnej za pomocą komponentu załadowanego przez trasę podrzędną jest usługa.

@Injectable() 
export class RouteParamService { 
    constructor(private routeParams: RouteParams) {} 

    get params() { 
    return this.routeParams.params; 
    } 
} 

@Component({ 
    template: 'Route Params: {{routeParams.params | json}}' 
}) 
export class EndPointComponent{ 
    constructor(private routeParams:RouteParamService){} 
} 

@Component({ 
    directives: [ROUTER_DIRECTIVES] 
    template: `<router-outlet></router-outlet>`, 
    providers: [RouteParamService] 
}) 
@RouteConfig([ 
    {path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true} 
]) 
class MiddleManComponent() { } 

RouteParamService zostanie instancja na tym samym poziomie co MiddleManComponent trasy i tak dostanie taką samą instancję RouteParams. Kiedy twoja usługa zostanie wstrzyknięta do komponentu trasy podrzędnej, uzyskasz dostęp do parametrów trasy nadrzędnej.

Jeśli potrzebujesz 2 instancji EndPointComponent do załadowania na różnych poziomach drzewek trasy, to myślę, że będziesz potrzebować innej warstwy rodzica; to jest element trasowany, który obejmuje zarówno MiddleManComponent, jak i EndPointComponent, między RootComponent.

RootComponent nie jest routowany, więc nie będzie można utworzyć z niego RouteParams dla RouteParamService. RouteParams jest dostarczany przez komponent <router-outlet>.

+0

Dziękuję. To naprawdę ciekawe rozwiązanie. Wydaje się nieco hacky, prawda? O ile wiesz, Angular 2 nie ma wbudowanego rozwiązania tego? Myślę, że mój przypadek użycia jest naprawdę powszechny, chyba że moja architektura komponentów jest źle pomyślana. PS: wbudowane rozwiązanie, jeśli istnieje, może być w '@ kątowym/routerze', a nie w starszym' @ kątowym/routerze-przestarzałym " – BeetleJuice

+0

Zaczyna czuć się hackerem, gdy próbujesz mieć ten sam komponent utworzony na innej trasie poziomy. Jeśli potrzebujesz parametrów trasy najwyższego poziomu, potrzebujesz komponentu przeznaczonego tylko do utworzenia usługi i przesunięcia pozostałych komponentów o jeden poziom. To jeden z powodów, dla których uważam, że to błąd projektu, że komponenty na najwyższym poziomie nie mają dostępu do RouteParams. Mimo to korzystanie z usług do udostępniania danych między komponentami jest powszechnym wzorcem dla aplikacji Angular. – awiseman

+0

Czuję się brudny robiąc to, ale działa. – BeetleJuice

1

Korzystanie z "@ kątowego/routera": "3.0.0-alpha.6" pakiet, udało mi się dostać argument trasach rodzic, wykonując następujące czynności:

export class ChildComponent { 

    private sub: any; 

    private parentRouteId: number; 

    constructor(
     private router: Router, 
     private route: ActivatedRoute) { 
    } 

    ngOnInit() { 
     this.sub = this.router.routerState.parent(this.route).params.subscribe(params => { 
      this.parentRouteId = +params["id"]; 
     }); 
    } 

    ngOnDestroy() { 
     this.sub.unsubscribe(); 
    } 
} 

W tym przykładzie trasa ma następujący format: /parent/:id/child/:childid

export const routes: RouterConfig = [ 
    { 
     path: '/parent/:id', 
     component: ParentComponent, 
     children: [ 
      { path: '/child/:childid', component: ChildComponent }] 
    } 
]; 
0

można wstrzyknąć ActivatedRote i podjąć migawka, jeszcze łatwiej:

constructor(private route: ActivatedRoute) {}; ngOnInit() { console.log('one of my parents route param:', this.route.snapshot.parent.params['PARAM-NAME']); }

+0

Dzięki. Odpowiedź, którą wybrałem, działała dla mnie w tym czasie. Angular zmienił się całkiem sporo od tego czasu i faktycznie zrobiłem dokładnie to, co sugerujesz od czasu przejścia na 'rc 4' lub' rc 5' – BeetleJuice

3

Korzystanie @angular/[email protected], można uzyskać dostęp do pa wynająć ActivatedRoute z

export class ChildComponent implements OnInit { 

    parentRouteId: string; 

    constructor(private route: ActivatedRoute) { 
    } 

    ngOnInit() { 
    this.route.parent.params 
     .subscribe((params: Params) => this.parentRouteId = params['id']); 
    } 
}