Suche…


Grundlegendes Routing

Der Router ermöglicht die Navigation von einer Ansicht zur anderen basierend auf den Benutzerinteraktionen mit der Anwendung.

Im Folgenden werden die Schritte zum Implementieren des grundlegenden Routings in Angular 2 beschrieben.

Grundlegende Vorsichtsmaßnahme : Stellen Sie sicher, dass Sie das Tag haben

    <base href='/'> 

als erstes Kind unter Ihrem Head-Tag in Ihrer index.html-Datei. Dieses Tag weist darauf hin, dass Ihr App-Ordner der Anwendungsstamm ist. Angular 2 würde dann wissen, um Ihre Links zu organisieren.

Zuerst überprüfen Sie, ob Sie in package.json auf korrekte / aktuelle Routing-Abhängigkeiten verweisen.

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

Der zweite Schritt besteht darin, die Route gemäß ihrer Klassendefinition zu definieren.

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

Importieren Sie in einer route/routes.ts ( route/routes.ts ) alle Komponenten, die Sie für verschiedene Routingpfade konfigurieren müssen. Ein leerer Pfad bedeutet, dass die Ansicht standardmäßig geladen wird. ":" im Pfad gibt dynamische Parameter an, die an die geladene Komponente übergeben werden.

Die Routen werden der Anwendung über die Abhängigkeitsinjektion zur Verfügung gestellt. Die ProviderRouter-Methode wird mit dem Parameter RouterConfig als Parameter aufgerufen, damit sie in die Komponenten eingefügt werden kann, um routingspezifische Aufgaben aufzurufen.

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

Der dritte Schritt besteht darin, den Routenanbieter zu booten.

In Ihrer main.ts (es kann ein beliebiger Name sein. Grundsätzlich sollte Ihre Hauptdatei in systemjs.config definiert sein.)

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

Der vierte Schritt ist das Laden / Anzeigen der Routerkomponenten basierend auf dem Pfad, auf den zugegriffen wird. Die Direktive wird verwendet, um den Winkel anzugeben, wo die Komponente geladen werden soll. Um den Import von ROUTER_DIRECTIVES zu verwenden.

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

Der fünfte Schritt besteht darin, die anderen Routen zu verknüpfen. Standardmäßig lädt RouterOutlet die Komponente, für die in der RouterConfig ein leerer Pfad angegeben ist. Die RouterLink-Anweisung wird mit dem HTML-Ankertag verwendet, um die an Routen angeschlossenen Komponenten zu laden. RouterLink generiert das href-Attribut, das zum Generieren von Links verwendet wird. 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 { }

Nun sind wir gut mit dem Routing zum statischen Pfad. RouterLink unterstützt den dynamischen Pfad auch, indem zusätzliche Parameter zusammen mit dem Pfad übergeben werden.

{Komponente} aus '@ angle / core' importieren; importiere {ROUTER_DIRECTIVES} von '@ angle / 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 verwendet ein Array, in dem das erste Element der Pfad für das Routing und die nachfolgenden Elemente die dynamischen Routing-Parameter sind.

Untergeordnete Routen

Manchmal ist es sinnvoll, Ansichten oder Routen ineinander zu verschachteln. Auf dem Dashboard möchten Sie beispielsweise mehrere Unteransichten, ähnlich wie Registerkarten, die jedoch über das Routingsystem implementiert werden, um die Projekte, Kontakte und Nachrichten der Benutzer anzuzeigen. Um solche Szenarien zu unterstützen, können Sie mit dem Router untergeordnete Routen definieren.

Zuerst passen wir unsere RouterConfig von oben an und fügen die untergeordneten Routen hinzu:

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

Nachdem wir nun unsere untergeordneten Routen definiert haben, müssen wir sicherstellen, dass diese untergeordneten Routen in unserer DashboardComponent angezeigt werden können, da wir die untergeordneten Routen hinzugefügt haben. Bisher haben wir erfahren, dass die Komponenten in einem <router-outlet></router-outlet> -Tag angezeigt werden. Ähnlich deklarieren wir ein weiteres RouterOutlet in der 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 { }

Wie Sie sehen, haben wir ein weiteres RouterOutlet hinzugefügt, in dem die RouterOutlet Routen angezeigt werden. Normalerweise wird die Route mit einem leeren Pfad angezeigt. Wir richten jedoch eine Weiterleitung zur projects , da diese sofort angezeigt werden soll, wenn die dashboard Route geladen wird. Davon abgesehen brauchen wir eine leere Route, ansonsten erhalten Sie eine Fehlermeldung wie diese:

Cannot match any routes: 'dashboard'

Durch Hinzufügen der leeren Route, dh einer Route mit einem leeren Pfad, haben wir einen Einstiegspunkt für den Router definiert.

ResolveData

In diesem Beispiel wird gezeigt, wie Sie aus einem Dienst abgerufene Daten auflösen können, bevor Sie die Ansicht Ihrer Anwendung darstellen.

Verwendet zum Zeitpunkt des Schreibens Winkel / Router 3.0.0-beta.2

Benutzer.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();
    }
}

Benutzer.Komponente.ts

Dies ist eine Seitenkomponente mit einer Liste aller Benutzer. Es funktioniert auf ähnliche Weise für die Komponente "Benutzerdetailseite". Ersetzen Sie data.users durch data.user oder den in app.routes.ts definierten Schlüssel (siehe unten).

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

Bündeln Sie optional mehrere Resolver zusammen.

WICHTIG: Dienste, die in Resolver verwendet werden, müssen zuerst importiert werden. Andernfalls wird der Fehler "Kein Anbieter für .. Resolver" angezeigt. Beachten Sie, dass diese Dienste weltweit verfügbar sind und Sie nicht mehr bei den providers einer Komponente providers werden müssen. Stellen Sie sicher, dass Sie sich von keinem Abonnement abmelden, um Speicherverluste zu vermeiden

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

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

main.browser.ts

Resolver müssen beim Bootstrapping injiziert werden.

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

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

Routing mit Kindern

Im Gegensatz zur Originaldokumentation habe ich festgestellt, dass dies der richtige Weg ist, um untergeordnete Routen in der Datei app.routing.ts oder app.module.ts richtig zu verschachteln (je nach Präferenz). Dieser Ansatz funktioniert bei Verwendung von WebPack oder SystemJS.

Das folgende Beispiel zeigt Routen für Home, Home / Counter und Home / Counter / Fetch-Daten. Die erste und letzte Route sind Beispiele für Weiterleitungen. Am Ende des Beispiels können Sie die zu importierende Route in einer separaten Datei exportieren. Für ex. app.module.ts

Angular erfordert, dass Sie über eine Pfadlose Route im untergeordneten Array verfügen, die die übergeordnete Komponente enthält, um die übergeordnete Route darzustellen. Dies ist ein wenig verwirrend, aber wenn Sie über eine leere URL für eine untergeordnete Route nachdenken, entspricht sie im Wesentlichen der gleichen URL wie die übergeordnete Route.

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 { }

Tolles Beispiel und Beschreibung über Siraj



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow