2016-05-16 10 views
5

My AppComponent ma dekorator @RouteConfig definiujący trasy najwyższego poziomu:Jak nawigować z komponentu potomnego do tras wyższego poziomu za pomocą macierzy paramerów łącza w angleular2?

@RouteConfig([ 
    { 
    path: '/', 
    name: 'Home', 
    component: HomeComponent 
    }, 
    { 
    path: '/about', 
    name: 'About', 
    component: AboutComponent 
    }, 
    { 
    path: '/profile/...', 
    name: 'Profile', 
    component: ProfileComponent 
    } 
]) 

export class AppComponent { 
} 

Moja ProfileComponent ma dekorator @RouteConfig definiujący trasy Profil podrzędne:

@RouteConfig([ 
    {path: '/', component: ProfileDetailsComponent, name: 'View', useAsDefault: true}, 
    {path: '/:id', component: ProfileDetailsComponent, name: 'Public'}, 
    {path: '/edit', component: ProfileEditorComponent, name: 'Edit'}, 
]) 

export class ProfileComponent { 
} 

Kiedy jestem w środku ProfileDetailsComponent Mogę wykonywać przekierowania do innych tras profilu, ale nie do innych. Chcę uniknąć podawania adresu URL za pomocą navigateByUrl i zamiast tego używać nazw tras, używając navigate. Np:

this.router.navigate(['View']); // Works 
this.router.navigate(['About']); // Raises error that it does not exist 

czytam tę odpowiedź tutaj: Angular 2 - How to navigate to another route using this.router.parent.navigate('/about')

Wykorzystuje:

this.router.parent.navigate(['About']); 

Który rodzaj ok, ale rozwiązuje mój problem tylko wtedy, gdy wiem, że w momencie zgłoszenia gdzie przekierowanie powinien iść. Mam wiele poziomów zagnieżdżania i ustalam trasę docelową w czasie wykonywania. Szukam sposobu na zrobienie czegoś w stylu:

this.router.navigate(['Level1', 'Level2', 'Level3']); 

Co pozwala mi śledzić gdzieś w pełni kwalifikowaną nazwę trasy docelowej. Czy jest to możliwe w jakikolwiek sposób?

Odpowiedz

4

W tym miejscu przyda się mikroserwis, sprawdź numer service docs here. Chodzi o to, że rodzic może słuchać żądań potomnych do nawigacji, a dziecko może nadawać te zmiany zgodnie z życzeniem.

Zacznijmy od prostego przedmiotu, który będzie przechowywał nazwę trasy i opcjonalne argumenty

export class NavArgs { 
    constructor(routeName: string, args?: any) { } 
} 

Teraz określić microservice z rxjs to jest naprawdę proste:

import { Injectable } from '@angular/core' 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class NavigationService { 
    private navigationRequestedSource = new Subject<string>(); 

    onNavigationRequested$ = this.navigationRequestedSource.asObservable(); 

    requestNaivation(navArg: string) { 
    this.navigationRequestedSource.next(mission) 
    } 
} 

Teraz element potomny może go zużyć i poprosić o nawigację:

export class SomeChild { 
    constructor(navService: NavigationService) { } 
    invoke() { 
     this.navService.requestNaivation(new NavArgs('SomeRoute')); 
    } 
} 

i składnik rodzic może słuchać do wspomnianego wniosku i działają na nim:

export class SomeParent { 
    constructor(navService: NavigationService, router: Router) { 
     this.navService 
      .onNavigationRequested$ 
      .subscribe((navArgs: NavArgs) => { 
       if (navArgs) { 
        if (navArgs.args) { 
         this.router.navigate([ navArgs.routeName, navArgs.args ]); 
        } 
        else { 
         this.router.navigate([ navArgs.routeName ]); 
        } 
       } 
     }); 
    }  
} 

Oczywiście jest to bardzo prosty przykład kodu, nie musiałoby być więcej importuje i obsługa błędów i takie. Ale mam nadzieję, że wpadniesz na ten pomysł.

Uwaga

Ważne jest, aby upewnić się, że zarówno rodzic i dziecko korzystać z tej samej instancji z tej usługi, aby to zrobić - musisz ustawić go jako provider na najwyższym poziomie, gdzie jest używane. Dzieje się tak dlatego, że domyślnie Angular2 tworzy singleton dla DI i stosuje podejście hierarchiczne. Musisz upewnić się, że nie ustawiłeś go błędnie na niższym poziomie, w przeciwnym razie nie zadziała.

+0

Podobnie jak pomysł, wydaje się schludny i generycznych, jak chciałem. Wypróbuję to po pracy i wrócę z uwagą! – fips

+1

To chyba dobry moment na uaktualnienie do nowego routera, jeśli korzystasz z wersji Release Angular 2, ponieważ rzeczy takie jak nazwy tras są teraz przestarzałe. – Dan

+0

Awesome to działało świetnie na wszystkich poziomach składników macierzystych/potomnych. Dziękuję Ci! – fips

6

Prefiks nazwy trasy z kreską, aby wskazać, że trasa jest trasą korzeń

this.router.navigate(['/About']); 
+0

Czy masz posty na blogu, które możesz udostępnić, które utworzyliście, widzę was cały czas tutaj, odpowiadając na wszystkie ** pytania Angular2 **? –

+0

Tak, zadziałało! Ale w moim scenariuszu potrzebuję elastyczności/abstrakcji, którą zapewnia inne rozwiązanie. Dziękuję Ci! – fips

Powiązane problemy