Ricerca…


Osservazioni

Ci sono alcuni altri trucchi che possiamo fare con il router (come limitare l'accesso), ma questi possono essere trattati in un tutorial separato.

Se hai bisogno di un nuovo percorso, modifica semplicemente app.routes.ts e segui i seguenti passi:

  1. Importa il componente
  2. Aggiungi all'array delle routes . Assicurati di includere un nuovo path e component .

bootstrapping

Ora che i percorsi sono definiti, dobbiamo far conoscere la nostra applicazione sui percorsi. Per fare ciò, avvia il provider che abbiamo esportato nell'esempio precedente.

Trova la tua configurazione di bootstrap (dovrebbe essere in main.ts , ma il tuo chilometraggio può variare ).

//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));

Configurazione del router-outlet

Ora che il router è configurato e la nostra app sa come gestire i percorsi, dobbiamo mostrare i componenti reali che abbiamo configurato.

Per fare ciò, configura il tuo modello / file HTML per il tuo componente di livello superiore (app) in questo modo:

//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>

L'elemento <router-outlet></router-outlet> cambierà il contenuto del percorso. Un altro aspetto positivo di questo elemento è che non deve essere l'unico elemento nel codice HTML.

Ad esempio: diciamo che volevi una barra degli strumenti in ogni pagina che rimane costante tra i percorsi, in modo simile a come appare Overflow dello stack. È possibile nidificare <router-outlet> sotto gli elementi in modo che cambino solo alcune parti della pagina.

Modifica dei percorsi (utilizzando modelli e direttive)

Ora che i percorsi sono impostati, abbiamo bisogno di un modo per cambiare effettivamente le rotte.

Questo esempio mostra come modificare le rotte usando il modello, ma è possibile modificare le rotte in TypeScript.

Ecco un esempio (senza binding):

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

Se l'utente fa clic su quel collegamento, si dirigerà verso /home . Il router sa come gestire /home , quindi mostrerà il componente Home .

Ecco un esempio con associazione dati:

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

Il che richiederebbe un array chiamato links esistere, quindi aggiungilo a app.ts :

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

Questo eseguirà un ciclo attraverso la matrice e aggiungerà un elemento <a> con la direttiva routerLink = il valore dell'elemento corrente nell'array, creando questo:

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

Questo è particolarmente utile se hai molti link, o forse i link devono essere costantemente modificati. Lasciamo che Angular gestisca il lavoro intenso di aggiungere collegamenti semplicemente fornendogli le informazioni necessarie.

Al momento, i links[] sono statici, ma è possibile alimentarli da un'altra fonte.

Impostazione delle rotte

NOTA: questo esempio si basa sulla versione 3.0.0.-beta.2 di @ angular / router. Al momento della stesura, questa è l'ultima versione del router.

Per utilizzare il router, definire le rotte in un nuovo file TypeScript come tale

//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);

Nella prima riga, importiamo provideRouter modo che possiamo consentire alla nostra applicazione di sapere quali sono i percorsi durante la fase di bootstrap.

Home e il Profile sono solo due componenti come esempio. Dovrai importare ogni Component hai bisogno come percorso.

Quindi, esportare la serie di percorsi.

path : il percorso del componente. NON HA BISOGNO DI UTILIZZARE '/ ........' Angolare lo farà automaticamente

component : il componente da caricare quando si accede al percorso

redirectTo : facoltativo . Se è necessario reindirizzare automaticamente un utente quando accede a un percorso particolare, fornire questo.

Infine, esportiamo il router configurato. provideRouter restituirà un provider che possiamo boostrap in modo che la nostra applicazione sappia come gestire ogni percorso.

Controllo dell'accesso ao da una rotta

Il router angolare predefinito consente la navigazione da e verso qualsiasi percorso in modo incondizionato. Questo non è sempre il comportamento desiderato.

In uno scenario in cui un utente può essere autorizzato a navigare da o verso una rotta, è possibile utilizzare una protezione di percorso per limitare questo comportamento.

Se il tuo scenario si adatta a uno dei seguenti, prendi in considerazione l'utilizzo di un Route Guard,

  • L'utente deve essere autenticato per navigare verso il componente di destinazione.
  • L'utente deve essere autorizzato a navigare verso il componente di destinazione.
  • Il componente richiede una richiesta asincrona prima dell'inizializzazione.
  • Il componente richiede l'input dell'utente prima di essere allontanato.

Come funzionano le Guardie della Route

Le guardie del percorso funzionano restituendo un valore booleano per controllare il comportamento della navigazione del router. Se viene restituito true , il router continuerà con la navigazione verso il componente di destinazione. Se viene restituito false , il router negherà la navigazione al componente di destinazione.


Route Guard Interfaces

Il router supporta più interfacce di protezione:

  • CanActivate : si verifica tra la navigazione del percorso.
  • CanActivateChild : si verifica tra la navigazione del percorso e un percorso secondario .
  • CanDeactivate : si verifica quando si naviga lontano dal percorso corrente.
  • CanLoad : si verifica tra la navigazione del percorso e un modulo funzione caricato in modo asincrono.
  • Risolvi : utilizzato per eseguire il recupero dei dati prima dell'attivazione del percorso.

Queste interfacce possono essere implementate in guardia per concedere o rimuovere l'accesso a determinati processi di navigazione.


Protezioni di percorso sincrone contro asincrone

Route Guards consente operazioni sincrone e asincrone per controllare in modo condizionale la navigazione.

Protezione di percorso sincrona

Una protezione di percorso sincrona restituisce un valore booleano, ad esempio calcolando un risultato immediato, al fine di controllare in modo condizionale la navigazione.

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

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

Protezione di percorso asincrona

Per un comportamento più complesso, una protezione di percorso può bloccare in modo asincrono la navigazione. Una protezione percorso asincrona può restituire un Osservabile o una Promessa.

Ciò è utile per situazioni come aspettare che l'input dell'utente risponda a una domanda, in attesa di salvare con successo le modifiche sul server o in attesa di ricevere i dati recuperati da un server remoto.

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;
        });
    }
}

Aggiungi guardia per instradare la configurazione

File app.routes

Le rotte protette possono canActivate a 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] }    
}

Esportare APP_ROUTER_PROVIDERS da utilizzare nel bootstrap dell'app

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

Usa Guard nel bootstrap dell'app

File main.ts (o boot.ts )

Considera gli esempi sopra:

  1. Crea la guardia (dove viene creata la Guardia) e
  2. Aggiungi guardia per instradare la configurazione , (dove Guard è configurato per il percorso, quindi viene esportato APP_ROUTER_PROVIDERS ),
    possiamo accoppiare il bootstrap a Guard come segue
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));

Usando Resolver e Guardie

Stiamo utilizzando una protezione di primo livello nella nostra configurazione di instradamento per catturare l'utente corrente sul caricamento della prima pagina e un resolver per memorizzare il valore di currentUser , che è il nostro utente autenticato dal back-end.

Una versione semplificata della nostra implementazione è la seguente:

Ecco la nostra rotta di primo livello:

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

Ecco il nostro 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);
 }
}

Ecco il nostro 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);
  }
}

Ecco il nostro 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow