Zoeken…


Opmerkingen

Er zijn nog een paar trucs die we met de router kunnen doen (zoals het beperken van toegang), maar die kunnen worden behandeld in een aparte tutorial.

Als u een nieuwe route nodig hebt, app.routes.ts u eenvoudig app.routes.ts en volgt u de volgende stappen:

  1. Importeer de component
  2. Voeg toe aan de routes array. Zorg ervoor dat u een nieuw path en een nieuw component .

bootstrapping

Nu de routes zijn gedefinieerd, moeten we onze toepassing op de hoogte stellen van de routes. Start hiervoor de provider die we in het vorige voorbeeld hebben geëxporteerd.

Zoek uw bootstrap-configuratie (moet in main.ts , maar uw kilometerstand kan variëren ).

//main.ts

import {bootstrap} from '@angular/platform-browser-dynamic';

//Import the App component (root component)
import { App } from './app/app';

//Also import the app routes
import { APP_ROUTES_PROVIDER } from './app/app.routes';

bootstrap(App, [
  APP_ROUTES_PROVIDER,
])
.catch(err => console.error(err));

Configureren router-outlet

Nu de router is geconfigureerd en onze app weet hoe met de routes moet worden omgegaan, moeten we de daadwerkelijke componenten weergeven die we hebben geconfigureerd.

Om dit te doen, configureert u uw HTML-sjabloon / bestand voor uw component op het hoogste niveau (app) als volgt:

//app.ts

import {Component} from '@angular/core';
import {Router, ROUTER_DIRECTIVES} from '@angular/router';

@Component({
    selector: 'app',
    templateUrl: 'app.html',
    styleUrls: ['app.css'],
    directives: [
        ROUTER_DIRECTIVES,
    ]
})
export class App {
    constructor() {
    }
}

<!-- app.html -->

<!-- All of your 'views' will go here -->
<router-outlet></router-outlet>

Het element <router-outlet></router-outlet> schakelt de inhoud op basis van de route. Een ander goed aspect van dit element is dat het niet het enige element in je HTML hoeft te zijn.

Bijvoorbeeld: Laten we zeggen dat u een werkbalk wilde op elke pagina die constant blijft tussen routes, vergelijkbaar met hoe Stack Overflow eruitziet. U kunt de <router-outlet> onder elementen nesten, zodat alleen bepaalde delen van de pagina veranderen.

Routes wijzigen (met behulp van sjablonen & richtlijnen)

Nu de routes zijn ingesteld, hebben we een manier nodig om routes daadwerkelijk te wijzigen.

In dit voorbeeld wordt getoond hoe u routes kunt wijzigen met behulp van de sjabloon, maar het is mogelijk om routes in TypeScript te wijzigen.

Hier is een voorbeeld (zonder binding):

<a routerLink="/home">Home</a>

Als de gebruiker op die link klikt, wordt deze naar /home . De router weet hoe hij /home moet verwerken, dus zal hij de Home Component weergeven.

Hier is een voorbeeld met gegevensbinding:

<a *ngFor="let link of links" [routerLink]="link">{{link}}</a>

app.ts zou een array met de naam links nodig zijn, dus voeg dit toe aan app.ts :

public links[] = [
    'home',
    'login'
]

Dit doorloopt de array en voegt een <a> -element toe met de routerLink instructie = de waarde van het huidige element in de array, waardoor dit wordt gemaakt:

 <a routerLink="home">home</a>
 <a routerLink="login">login</a>

Dit is vooral handig als u veel links hebt, of misschien moeten de links voortdurend worden gewijzigd. We laten Angular het drukke werk van het toevoegen van links uitvoeren door het de informatie te geven die het nodig heeft.

Op dit moment zijn links[] statisch, maar het is mogelijk om gegevens van een andere bron in te voeren.

Routes instellen

OPMERKING: Dit voorbeeld is gebaseerd op de 3.0.0.-beta.2 release van de @ angular / router. Op het moment van schrijven is dit de nieuwste versie van de router.

Als u de router wilt gebruiken, definieert u routes in een nieuw TypeScript-bestand als zodanig

//app.routes.ts

import {provideRouter} from '@angular/router';

import {Home} from './routes/home/home';
import {Profile} from './routes/profile/profile';

export const routes = [
    {path: '', redirectTo: 'home'},
    {path: 'home', component: Home},
    {path: 'login', component: Login},
];

export const APP_ROUTES_PROVIDER = provideRouter(routes);

In de eerste regel importeren we provideRouter zodat we onze applicatie kunnen laten weten wat de routes zijn tijdens de bootstrap-fase.

Home en Profile zijn slechts twee componenten als voorbeeld. U moet elke Component u nodig hebt als route importeren.

Exporteer vervolgens de reeks routes.

path : het pad naar de component. U MOET '/ ........' NIET GEBRUIKEN. Angular doet dit automatisch

component : het te laden component wanneer de route wordt betreden

redirectTo : Optioneel . Als u een gebruiker automatisch moet omleiden wanneer deze een bepaalde route bezoekt, geeft u dit op.

Ten slotte exporteren we de geconfigureerde router. provideRouter retourneert een provider die we kunnen boostrap zodat onze applicatie weet hoe elke route moet worden afgehandeld.

Toegang tot of vanaf een route beheren

De standaard Angular-router maakt onvoorwaardelijke navigatie van en naar elke route mogelijk. Dit is niet altijd het gewenste gedrag.

In een scenario waarin een gebruiker voorwaardelijk toestemming krijgt om naar of van een route te navigeren, kan een Route Guard worden gebruikt om dit gedrag te beperken.

Als uw scenario aan een van de volgende voorwaarden voldoet, kunt u overwegen een routebewaking te gebruiken,

  • De gebruiker moet worden geverifieerd om naar de doelcomponent te navigeren.
  • De gebruiker moet geautoriseerd zijn om naar de doelcomponent te navigeren.
  • Onderdeel vereist asynchrone aanvraag vóór initialisatie.
  • Component vereist gebruikersinvoer voordat er vanaf wordt genavigeerd.

Hoe Route Guards werken

Routebewakers werken door een booleaanse waarde te retourneren om het gedrag van routernavigatie te regelen. Als true wordt geretourneerd, gaat de router door met navigeren naar de doelcomponent. Als false wordt geretourneerd, weigert de router de navigatie naar de doelcomponent.


Route Guard-interfaces

De router ondersteunt meerdere bewakingsinterfaces:

  • CanActivate : vindt plaats tussen routenavigatie.
  • CanActivateChild : vindt plaats tussen routenavigatie naar een onderliggende route.
  • Kan deactiveren : vindt plaats bij het navigeren van de huidige route.
  • CanLoad : vindt plaats tussen routenavigatie naar een functiemodule die asynchroon is geladen.
  • Oplossen : wordt gebruikt om gegevens op te halen vóór activering van de route.

Deze interfaces kunnen in uw wacht worden geïmplementeerd om toegang tot bepaalde navigatieprocessen te verlenen of te verwijderen.


Synchrone versus asynchrone routewachten

Routebewakers maken synchrone en asynchrone bewerkingen mogelijk om de navigatie voorwaardelijk te regelen.

Synchrone Route Guard

Een synchrone routebewaker retourneert een Boolean, bijvoorbeeld door een onmiddellijk resultaat te berekenen, om de navigatie voorwaardelijk te regelen.

import { Injectable }     from '@angular/core';
import { CanActivate }    from '@angular/router';

@Injectable()
export class SynchronousGuard implements CanActivate {
  canActivate() {
    console.log('SynchronousGuard#canActivate called');
    return true;
  }
}

Asynchrone routebewaking

Voor complexer gedrag kan een routebewaker de navigatie asynchroon blokkeren. Een asynchrone routebewaker kan een waarneembare of een belofte teruggeven.

Dit is handig voor situaties zoals wachten op gebruikersinvoer om een vraag te beantwoorden, wachten op het succesvol opslaan van wijzigingen op de server of wachten op het ontvangen van gegevens die zijn opgehaald van een externe server.

import { Injectable }     from '@angular/core';
import { CanActivate, Router, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable }     from 'rxjs/Rx';
import { MockAuthenticationService } from './authentication/authentication.service';

@Injectable()
export class AsynchronousGuard implements CanActivate {
    constructor(private router: Router, private auth: MockAuthenticationService) {}

    canActivate(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<boolean>|boolean {
        this.auth.subscribe((authenticated) => {
            if (authenticated) {
                return true;
            }
            this.router.navigateByUrl('/login');
            return false;
        });
    }
}

Bewaker toevoegen aan routeconfiguratie

Bestand app.routes

Beveiligde routes kunnen canActivate aan Guard

import { provideRouter, Router, RouterConfig, CanActivate } from '@angular/router';

//components
import { LoginComponent } from './login/login.component';
import { DashboardComponent } from './dashboard/dashboard.component';

export const routes: RouterConfig = [
    { path: 'login', component: LoginComponent },
    { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }    
}

Exporteer de APP_ROUTER_PROVIDERS om te gebruiken in de bootstrap van de app

export const APP_ROUTER_PROVIDERS = [
    AuthGuard,
    provideRouter(routes)
];

Gebruik Guard in bootstrap van de app

Bestand main.ts (of boot.ts )

Overweeg de bovenstaande voorbeelden:

  1. Maak de bewaker (waar de bewaker is gemaakt) en
  2. Bewaker toevoegen aan routeconfiguratie , (waarbij de bewaker is geconfigureerd voor route, dan wordt APP_ROUTER_PROVIDERS geëxporteerd),
    we kunnen de bootstrap als volgt koppelen aan Guard
import { bootstrap } from '@angular/platform-browser-dynamic';
import { provide } from '@angular/core';

import { APP_ROUTER_PROVIDERS } from './app.routes';    
import { AppComponent } from './app.component';

bootstrap(AppComponent, [
    APP_ROUTER_PROVIDERS
])
.then(success => console.log(`Bootstrap success`))
.catch(error => console.log(error));

Resolvers en bewakers gebruiken

We gebruiken een bewaker op topniveau in onze routeconfiguratie om de huidige gebruiker bij het laden van de eerste pagina te vangen, en een resolver om de waarde van de currentUser te slaan, onze geverifieerde gebruiker van de backend.

Een vereenvoudigde versie van onze implementatie ziet er als volgt uit:

Hier is onze route op het hoogste niveau:

export const routes = [
{
  path: 'Dash',
  pathMatch : 'prefix',
  component: DashCmp,
  canActivate: [AuthGuard],
  resolve: {
      currentUser: CurrentUserResolver
  },
  children: [...[
    path: '',
    component: ProfileCmp,
    resolve: {
        currentUser: currentUser
    }
  ]]
  }
];

Hier is onze AuthService

import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import 'rxjs/add/operator/do';

@Injectable()
export class AuthService {
  constructor(http: Http) {
    this.http = http;

    let headers = new Headers({ 'Content-Type': 'application/json' });
    this.options = new RequestOptions({ headers: headers });
  }
  fetchCurrentUser() {
    return this.http.get('/api/users/me')
      .map(res => res.json())
      .do(val => this.currentUser = val);
 }
}

Hier is onze AuthGuard :

import { Injectable } from '@angular/core';
import { CanActivate } from "@angular/router";
import { Observable } from 'rxjs/Rx';

import { AuthService } from '../services/AuthService';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(auth: AuthService) {
    this.auth = auth;
  }
  canActivate(route, state) {
    return Observable
      .merge(this.auth.fetchCurrentUser(), Observable.of(true))
      .filter(x => x == true);
  }
}

Hier is onze CurrentUserResolver :

import { Injectable } from '@angular/core';
import { Resolve } from "@angular/router";
import { Observable } from 'rxjs/Rx';

import { AuthService } from '../services/AuthService';

@Injectable()
export class CurrentUserResolver implements Resolve {
  constructor(auth: AuthService) {
    this.auth = auth;
  }
  resolve(route, state) {
    return this.auth.currentUser;
  }
}


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow