Angular 2
routing
Sök…
Grundläggande dirigering
Routern möjliggör navigering från en vy till en annan baserad på användarinteraktioner med applikationen.
Följande är stegen för att implementera grundläggande routing i Angular 2 -
Grundläggande försiktighetsåtgärd : Se till att du har taggen
<base href='/'>
som det första barnet under ditt huvudtagg i din index.html-fil. Den här taggen berättar att din appmapp är programroten. Angular 2 skulle då veta hur du organiserar dina länkar.
Det första steget är att kontrollera om du pekar på rätt / senaste routingberoende i package.json -
"dependencies": {
......
"@angular/router": "3.0.0-beta.1",
......
}
Det andra steget är att definiera rutten enligt sin klassdefinition -
class Route {
path : string
pathMatch : 'full'|'prefix'
component : Type|string
.........
}
I en ruttfil ( route/routes.ts
), importera alla komponenter som du behöver konfigurera för olika ruttvägar. Tom sökväg innebär att vyn laddas som standard. ":" i sökvägen indikerar dynamisk parameter som skickas till den laddade komponenten.
Rutter görs tillgängliga för applikation via beroendeinjektion. ProviderRouter-metoden kallas med RouterConfig som parameter så att den kan injiceras till komponenterna för att ringa routing specifika uppgifter.
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)];
Det tredje steget är att starta om ruttleverantören.
I din main.ts
(Det kan vara vilket namn som helst. I princip bör den vara din huvudfil definierad i 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));
Det fjärde steget är att ladda / visa routerkomponenterna baserat på åtkomst till sökvägen. direktivet används för att säga vinklat var komponenten ska laddas. För att använda importera 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]
})
Femte steget är att länka de andra rutterna. Som standard kommer RouterOutlet att ladda den komponent för vilken tom sökväg anges i RouterConfig. RouterLink-direktivet används med html-ankaretikett för att ladda komponenterna som är kopplade till rutter. RouterLink genererar href-attributet som används för att generera länkar. För ex:
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 { }
Nu är vi bra med routing till statisk väg. RouterLink stöder dynamisk väg också genom att skicka extra parametrar tillsammans med sökvägen.
importera {Komponent} från '@ vinkel / kärna'; importera {ROUTER_DIRECTIVES} från '@ vinkel / 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 tar en matris där det första elementet är vägen för routing och efterföljande element är för de dynamiska routingparametrarna.
Barnvägar
Ibland är det vettigt att häcka vyer eller rutter inom varandra. Till exempel på instrumentpanelen vill du ha flera undervyer, liknande flikar men implementerade via routingsystemet, för att visa användarnas projekt, kontakter, meddelanden och. För att stödja sådana scenarier tillåter routern oss att definiera barnvägar.
Först justerar vi vår RouterConfig
ovanifrån och lägger till barnvägarna:
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 }
];
Nu när vi har våra barneruter definierade måste vi se till att dessa barnvägar kan visas i vår DashboardComponent
, eftersom det är där vi har lagt barnen till. Tidigare har vi lärt oss att komponenterna visas i en <router-outlet></router-outlet>
-tagg. På liknande sätt förklarar vi en annan RouterOutlet
i 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 { }
Som ni ser har vi lagt till en annan RouterOutlet
där RouterOutlet
kommer att visas. Vanligtvis kommer rutten med en tom sökväg att visas, men vi ställer in en omdirigering till projects
rutt, eftersom vi vill att den ska visas omedelbart när dashboard
rutt laddas. Med det sagt, vi behöver en tom rutt, annars får du ett fel så här:
Cannot match any routes: 'dashboard'
Så genom att lägga till den tomma rutten, vilket betyder en rutt med en tom sökväg, har vi definierat en startpunkt för routern.
ResolveData
Det här exemplet visar hur du kan lösa data hämtade från en tjänst innan du visar din applikationsvy.
Använder vinkel / router 3.0.0-beta.2 i skrivande stund
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
Detta är en sidkomponent med en lista över alla användare. Det fungerar på liknande sätt för data.users
data.user
, ersätt data.users
med data.user
eller vilken nyckel som definieras i app.routes.ts (se nedan)
... 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
Packa eventuellt flera upplösare tillsammans.
VIKTIGT: Tjänster som används i resolver måste importeras först eller så får du en 'Ingen leverantör för ..Resolver-fel'. Kom ihåg att dessa tjänster kommer att finnas tillgängliga över hela världen och att du inte kommer att behöva deklarera dem i någon komponents providers
längre. Se till att avbeställa prenumerationen för att förhindra läckage av minnet
... import { UsersService } from './users.service'; import { UsersResolver } from './users.resolver'; export const ROUTE_RESOLVERS = [ ..., UsersService, UsersResolver ]
main.browser.ts
Resolver måste injiceras under bootstrapping.
... import {bootstrap} from '@angular/platform-browser-dynamic'; import { ROUTE_RESOLVERS } from './app.resolver'; bootstrap(<Type>App, [ ... ...ROUTE_RESOLVERS ]) .catch(err => console.error(err));
Rutning med barn
I motsats till originaldokumentationen fann jag att det här var sättet att ordentligt bo bo barnvägar inuti app.routing.ts eller app.module.ts-filen (beroende på vad du föredrar). Den här metoden fungerar när du använder antingen WebPack eller SystemJS.
Exemplet nedan visar rutter för hem, hem / räknare och hem / räknare / hämta data. De första och sista vägarna är exempel på omdirigeringar. Slutligen i slutet av exemplet är ett korrekt sätt att exportera den väg som ska importeras i en separat fil. För ex. app.module.ts
För att ytterligare förklara, kräver Angular att du har en ruttlös rutt i barnfältet som inkluderar överordnad komponent, för att representera överordnad rutt. Det är lite förvirrande, men om du tänker på en tom URL-adress för en barnväg, skulle den i princip motsvara samma URL som överordnad rutt.
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 { }
Bra exempel och beskrivning via Siraj