Ricerca…


Routing di base

Il router abilita la navigazione da una vista all'altra in base alle interazioni dell'utente con l'applicazione.

Di seguito sono riportate le fasi di implementazione del routing di base in Angular 2:

Precauzione di base : assicurati di avere il tag

    <base href='/'> 

come il primo figlio sotto il tag head nel file index.html. Questo tag indica che la cartella dell'app è la root dell'applicazione. Angular 2 saprebbe quindi organizzare i tuoi collegamenti.

Il primo passo è controllare se stai puntando a corrette / ultime dipendenze di routing in package.json -

"dependencies": {
  ......
  "@angular/router": "3.0.0-beta.1",
  ......
}

Il secondo passo è definire il percorso come da sua definizione di classe -

class Route {
  path : string
  pathMatch : 'full'|'prefix'
  component : Type|string
  .........
}

In un file di rotte ( route/routes.ts ), importa tutti i componenti che devi configurare per percorsi di routing differenti. Percorso vuoto significa che la vista è caricata di default. ":" nel percorso indica il parametro dinamico passato al componente caricato.

Le rotte sono rese disponibili per l'applicazione tramite l'iniezione dipendente. Il metodo ProviderRouter viene chiamato con RouterConfig come parametro, in modo che possa essere iniettato ai componenti per chiamare le attività specifiche del routing.

import { provideRouter, RouterConfig } from '@angular/router';
import { BarDetailComponent } from '../components/bar-detail.component';
import { DashboardComponent } from '../components/dashboard.component';
import { LoginComponent } from '../components/login.component';
import { SignupComponent } from '../components/signup.component';

export const appRoutes: RouterConfig = [
  { path: '', pathMatch: 'full', redirectTo: 'login' },
  { path: 'dashboard', component: DashboardComponent },
  { path: 'bars/:id', component: BarDetailComponent },
  { path: 'login', component: LoginComponent },
  { path: 'signup',   component: SignupComponent }
];

export const APP_ROUTER_PROVIDER = [provideRouter(appRoutes)];

Il terzo passaggio consiste nel riavviare il provider di route.

Nel tuo main.ts (può essere un nome qualsiasi, in pratica, dovrebbe il tuo file principale definito in systemjs.config)

import { bootstrap } from '@angular/platform-browser-dynamic';
import { AppComponent } from './components/app.component';
import { APP_ROUTER_PROVIDER } from "./routes/routes";

bootstrap(AppComponent, [ APP_ROUTER_PROVIDER ]).catch(err => console.error(err));

Il quarto passaggio consiste nel caricare / visualizzare i componenti del router in base al percorso cui si accede. la direttiva è usata per dire angolare dove caricare il componente. Per utilizzare importare ROUTER_DIRECTIVES.

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

@Component({
  selector: 'demo-app',
  template: `
    ....................................
    <div>
      <router-outlet></router-outlet>
    </div>
    ....................................
  `,
  // Add our router directives we will be using
  directives: [ROUTER_DIRECTIVES]
})

Il quinto passo è quello di collegare gli altri percorsi. Per impostazione predefinita, RouterOutlet caricherà il componente per il quale il percorso vuoto è specificato in RouterConfig. La direttiva RouterLink viene utilizzata con il tag di ancoraggio html per caricare i componenti collegati alle rotte. RouterLink genera l'attributo href che viene utilizzato per generare collegamenti. Per esempio:

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

@Component({
  selector: 'demo-app',
  template: `
    <a [routerLink]="['/login']">Login</a>
    <a [routerLink]="['/signup']">Signup</a>      
    <a [routerLink]="['/dashboard']">Dashboard</a>
    <div>
      <router-outlet></router-outlet>
    </div>
  `,
  // Add our router directives we will be using
  directives: [ROUTER_DIRECTIVES]
})
export class AppComponent { }

Ora, siamo bravi con il routing al percorso statico. RouterLink supporta il percorso dinamico anche passando parametri aggiuntivi insieme al percorso.

importare {Component} da '@ angular / core'; importare {ROUTER_DIRECTIVES} da '@ angular / router';

@Component({
  selector: 'demo-app',
  template: `
        <ul>
          <li *ngFor="let bar of bars | async">
            <a [routerLink]="['/bars', bar.id]">
              {{bar.name}}
            </a>
          </li>
        </ul>
    <div>
      <router-outlet></router-outlet>
    </div>
  `,
  // Add our router directives we will be using
  directives: [ROUTER_DIRECTIVES]
})
export class AppComponent { }

RouterLink accetta un array in cui il primo elemento è il percorso per il routing e gli elementi successivi sono per i parametri di routing dinamico.

Percorsi per bambini

A volte ha senso annidare viste o rotte l'una dentro l'altra. Ad esempio sul cruscotto si desiderano diverse viste secondarie, simili alle schede ma implementate tramite il sistema di routing, per mostrare i progetti, i contatti, i messaggi degli utenti. Per supportare tali scenari, il router ci consente di definire percorsi figlio.

Per prima cosa RouterConfig nostro RouterConfig dall'alto e aggiungiamo le rotte RouterConfig :

import { ProjectsComponent } from '../components/projects.component';
import { MessagesComponent} from '../components/messages.component';

export const appRoutes: RouterConfig = [
  { path: '', pathMatch: 'full', redirectTo: 'login' },
  { path: 'dashboard', component: DashboardComponent,
    children: [
      { path: '', redirectTo: 'projects', pathMatch: 'full' },
      { path: 'projects', component: 'ProjectsComponent' },
      { path: 'messages', component: 'MessagesComponent' }
    ] },
  { path: 'bars/:id', component: BarDetailComponent },
  { path: 'login', component: LoginComponent },
  { path: 'signup',   component: SignupComponent }
];

Ora che abbiamo definito le rotte del nostro bambino, dobbiamo assicurarci che le rotte dei bambini possano essere visualizzate all'interno del nostro DashboardComponent , poiché è lì che abbiamo aggiunto i bambini. In precedenza abbiamo appreso che i componenti sono visualizzati in un <router-outlet></router-outlet> . Analogamente dichiariamo un altro RouterOutlet in DashboardComponent :

import { Component } from '@angular/core';

@Component({
  selector: 'dashboard',
  template: `
    <a [routerLink]="['projects']">Projects</a>
    <a [routerLink]="['messages']">Messages</a>   
    <div>
      <router-outlet></router-outlet>
    </div>
  `
})
export class DashboardComponent { }

Come puoi vedere, abbiamo aggiunto un altro RouterOutlet in cui verranno visualizzate le rotte RouterOutlet . Di solito viene mostrata la rotta con un percorso vuoto, tuttavia, impostiamo un reindirizzamento sulla rotta dei projects , perché vogliamo che vengano mostrati immediatamente quando viene caricato il percorso del dashboard . Detto questo, abbiamo bisogno di un percorso vuoto, altrimenti riceverai un errore come questo:

Cannot match any routes: 'dashboard'

Quindi, aggiungendo il percorso vuoto , ovvero un percorso con un percorso vuoto, abbiamo definito un punto di ingresso per il router.

ResolveData

Questo esempio ti mostrerà come puoi risolvere i dati recuperati da un servizio prima di mostrare la vista dell'applicazione.

Utilizza angular / router 3.0.0-beta.2 al momento della scrittura

users.service.ts

...
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { User } from './user.ts';



@Injectable()
export class UsersService {

    constructor(public http:Http) {}

    /**
     * Returns all users
     * @returns {Observable<User[]>}
     */
    index():Observable<User[]> {

        return this.http.get('http://mywebsite.com/api/v1/users')
            .map((res:Response) => res.json());
    }

    /**
     * Returns a user by ID
     * @param id
     * @returns {Observable<User>}
     */
    get(id:number|string):Observable<User> {

        return this.http.get('http://mywebsite.com/api/v1/users/' + id)
            .map((res:Response) => res.json());
    }
}

users.resolver.ts

...
import { UsersService } from './users.service.ts';
import { Observable } from 'rxjs/Rx';
import {
    Resolve,
    ActivatedRouteSnapshot,
    RouterStateSnapshot
} from "@angular/router";




@Injectable()
export class UsersResolver implements Resolve<User[] | User> {

    // Inject UsersService into the resolver
    constructor(private service:UsersService) {}

    resolve(route:ActivatedRouteSnapshot, state:RouterStateSnapshot):Observable<User[] | User> {
        // If userId param exists in current URL, return a single user, else return all users
        // Uses brackets notation to access `id` to suppress editor warning, may use dot notation if you create an interface extending ActivatedRoute with an optional id? attribute
        if (route.params['id']) return this.service.get(route.params['id']);
        return this.service.index();
    }
}

users.component.ts

Questo è un componente di pagina con un elenco di tutti gli utenti. data.users allo stesso modo per il componente della pagina dei dettagli Utente, sostituirà data.users con data.user o qualsiasi altra chiave definita in app.routes.ts (vedi sotto)

...
import { ActivatedRoute} from "@angular/router";



@Component(...)
export class UsersComponent {

    users:User[];


    constructor(route: ActivatedRoute) {
        route.data.subscribe(data => {
            // data['Match key defined in RouterConfig, see below']
            this.users = data.users;
        });
    }

    /**
     * It is not required to unsubscribe from the resolver as Angular's HTTP
     * automatically completes the subscription when data is received from the server
     */
}

app.routes.ts

...
import { UsersResolver } from './resolvers/users.resolver';



export const routes:RouterConfig = <RouterConfig>[
    ...
    {
        path: 'user/:id',
        component: UserComponent,
        resolve: {
            // hence data.user in UserComponent
            user: UsersResolver
        }
    },
    {
        path: 'users',
        component: UsersComponent,
        resolve: {
            // hence data.users in UsersComponent, note the pluralisation
            users: UsersResolver
        }
    },
    ...
]
...

app.resolver.ts

Opzionalmente raggruppa più risolutori insieme.

IMPORTANTE: i servizi utilizzati in resolver devono essere importati per primi o si otterrà un 'Nessun provider per ... Errore Risolutore'. Ricorda che questi servizi saranno disponibili a livello globale e non dovrai più dichiararli in alcun providers di componenti. Assicurati di annullare l'iscrizione a qualsiasi abbonamento per evitare perdite di memoria

...
import { UsersService } from './users.service';
import { UsersResolver } from './users.resolver';

export const ROUTE_RESOLVERS = [
    ...,
    UsersService,
    UsersResolver
]

main.browser.ts

I resolver devono essere iniettati durante il bootstrap.

...
import {bootstrap} from '@angular/platform-browser-dynamic';
import { ROUTE_RESOLVERS } from './app.resolver';

bootstrap(<Type>App, [
    ...
    ...ROUTE_RESOLVERS
])
.catch(err => console.error(err));

Instradamento con i bambini

Contrariamente alla documentazione originale, ho trovato questo modo di annidare correttamente le rotte dei bambini all'interno del file app.routing.ts o app.module.ts (a seconda delle preferenze). Questo approccio funziona quando si utilizza WebPack o SystemJS.

L'esempio seguente mostra i percorsi per casa, casa / contatore e home / contatore / fetch-data. Il primo e l'ultimo instradamento sono esempi di reindirizzamenti. Alla fine dell'esempio, infine, c'è un modo corretto per esportare il percorso da importare in un file separato. Per es. app.module.ts

Per spiegare ulteriormente, Angular richiede di avere un percorso senza percorsi nell'array per bambini che include il componente principale, per rappresentare la rotta principale. È un po 'confuso, ma se si pensa a un URL vuoto per un percorso figlio, equivarrebbe sostanzialmente allo stesso URL del percorso principale.

import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";

import { HomeComponent } from "./components/home/home.component";
import { FetchDataComponent } from "./components/fetchdata/fetchdata.component";
import { CounterComponent } from "./components/counter/counter.component";

const appRoutes: Routes = [
    {
        path: "",
        redirectTo: "home",
        pathMatch: "full"
    },
    {
        path: "home",            
        children: [
            {
                path: "",
                component: HomeComponent
            },
            {
                path: "counter",                    
                children: [
                    {
                        path: "",
                        component: CounterComponent
                    },
                    {
                        path: "fetch-data",
                        component: FetchDataComponent                            
                    }
                ]
            }
        ]
    },
    {
        path: "**",
        redirectTo: "home"
    }
];

@NgModule({
    imports: [
        RouterModule.forRoot(appRoutes)
    ],
    exports: [
        RouterModule
    ]
})
export class AppRoutingModule { }

Ottimo esempio e descrizione tramite Siraj



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow