Angular 中间部分 2.3 路由
来源:互联网 发布:手机大字体软件 编辑:程序博客网 时间:2024/06/07 02:20
路由
Angular路由包括:基础路由,路由策略,路由参数,Auth,login,子路由
基础&安装
anchor tag
页面指定内容快速访问
在html设定<a name="about"><h1>About</h1></a>
访问http://something/#about
即可到h1
tag
Angular 有如下配置路由
- Routes 这个应用支持的路由
- RouterOutlet 路由和对应的内容
- RouterLink 连接路由
导入 route 模块 p220,p243
import { RouterModule, Routes} from '@angular/router';
在app.module.ts
定义路由
const routes: Routes = [ // 普通路由 { path: '', redirectTo: 'home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'about', component: AboutComponent }, // 认证路由 { path: 'login', component: LoginComponent }, { path: 'protected', component: ProtectedComponent, canActivate: [ LoggedInGuard ] }, // 层叠路由 nested { path: 'products', component: ProductsComponent, children: childRoutes }];
path
就是路径,component
就是对应的组件
redirectTo
就是重定向一个新的路径
访问 http://localhost:4200/#/
会被重定向到home
同时需要在app.module.ts
的@NgModule({
导入 RouterModule.forRoot(routes)
imports: [ ... RouterModule.forRoot(routes), ProductsModule],
RouterOutlet
当改变路由的时候,最好模版的样式不会改变,只是页面的部分内容重新渲染。
**The router-outlet element indicates where the contents of each route component will be
rendered**
定义每一个组件的哪些内容会被渲染
在组件app.component.ts内配置
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css']})export class AppComponent { constructor(private router: Router) { };}
在html页面
<div class="page-header"> <div class="container"> <h1>Router Sample</h1> <div class="navLinks"> <a [routerLink]="['/home']">Home</a> <a [routerLink]="['/about']">About Us</a> <a [routerLink]="['/contact']">Contact Us</a> | <a [routerLink]="['/products']">Products</a> <a [routerLink]="['/login']">Login</a> <a [routerLink]="['/protected']">Protected</a> </div> </div></div><div id="content"> <div class="container"> <router-outlet></router-outlet> </div></div>
router-outlet
在导航栏的下面, routerLink
指引对应的路由
相比直接设置对应路由: <a href="/#/home">Home</a>
好处是保持单一页面,而不是重新加载新页面。
put it together
在html
页面的head
中
<head> ... <base href="/"></head>
包含了路由情况
Angualr通过NgModule的APP_BASE_HREF
来配置base而不用直接更改
在NgModule导入APP_BASE_HREF
@NgModule({ providers: [ { provide: LocationStrategy, useClass: HashLocationStrategy }, { provide: APP_BASE_HREF, useValue: '/' } ]})
先创建3个子组件,在创建父组件连接
p229 p252 父组件设置路由
在app.moudyle.ts导入组件(RouterModule,Routes)
并配置对应的路由
const routes: Routes = [{ path: '', redirectTo: 'home', pathMatch: 'full' },
@NgModule({
导入
在html设置对应子组件连接,导航栏,(routerLink,router-outlet)
路由策略 Routing Strategies
默认是PathLocationStrategy,也就是html5默认路由。这个策略下,路由由普通路径组成比如 /home
但同时,HashLocationStrategy也在被使用
但使用HTML5路由时,URL会由普通路径结束。也就是不使用hash/anchor
假设刷新页面时,不会请求根路径,而是/about,但是在服务器端并没有配置,(只配置根路径),会返回404?
所以hTML5默认必须把所有路径都配置。
详细比较见
https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling
HashLocationStrategy使用/#/home
路由参数 /route/:param
当每篇文章都有对应的url id时 /articles/3
/articles/4
需要配置 /route/:param
安装 p235 p258
导入ActivatedRoute
import { ActivatedRoute } from '@angular/router';
设置路由 { path: 'product/:id', component: ProductComponent },
把ActivatedRoute加入到constructor
export class ProductComponent { id: string; constructor(private route: ActivatedRoute) route.params.subscribe(params => { this.id = params['id']; }); }}
Music search app
P236 P256
Router Hooks login
认证+认证后能访问的内容
P253 P276
AuthService
写AuthService
import { Injectable } from '@angular/core';@Injectable()export class AuthService { login(user: string, password: string): boolean { if (user === 'user' && password === 'password') { localStorage.setItem('username', user); return true; } \\ 当use和password匹配时,返回true,并且储存在localStorage, return false; } logout(): any { localStorage.removeItem('username'); } getUser(): any { return localStorage.getItem('username'); } isLoggedIn(): boolean { return this.getUser() !== null; }} //provide注入注册export const AUTH_PROVIDERS: Array<any> = [ { provide: AuthService, useClass: AuthService }];
在 login的组件注入
export class LoginComponent { message: string; constructor(public authService: AuthService) { this.message = ''; } login(username: string, password: string): boolean { this.message = ''; if (!this.authService.login(username, password)) { this.message = 'Incorrect credentials.'; setTimeout(function() { this.message = ''; }.bind(this), 2500); } return false; } logout(): boolean { this.authService.logout(); return false; }}
在login的html
<h1>Login</h1>//认证错误信息<div class="alert alert-danger" role="alert" *ngIf="message"> {{ message }}</div>//使用*ngIf="!authService.getUser()"来认证信息输入<form class="form-inline" *ngIf="!authService.getUser()"> <div class="form-group"> <label for="username">User: (type <em>user</em>)</label> <input class="form-control" name="username" #username> </div> <div class="form-group"> <label for="password">Password: (type <em>password</em>)</label> <input class="form-control" type="password" name="password" #password> </div> <a class="btn btn-default" (click)="login(username.value, password.value)"> Submit </a></form>//认证成功<div class="well" *ngIf="authService.getUser()"> Logged in as <b>{{ authService.getUser() }}</b> <a href (click)="logout()">Log out</a></div>
ProtectedComponent p258 p281
只让登入用户访问
创建 logged-in.guard.ts
快速创建Angular内置:
ng generate guard logged-in
/* tslint:disble max-line-length */import { Injectable } from '@angular/core';import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';import { Observable } from 'rxjs/Observable';import { AuthService } from './auth.service';@Injectable()export class LoggedInGuard implements CanActivate { //注入AuthService constructor(private authService: AuthService) {} //CanActivate检测authService canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean { const isLoggedIn = this.authService.isLoggedIn(); console.log('canActivate', isLoggedIn); return isLoggedIn; }}
使用了 CanActivate,并且注入AuthService
配置路由器 p259 p282
在app.module.ts导入AUTH_PROVIDERS和LoggedInGuard
在app.module 认证路由 见开篇路由配置
并provider p260 p283
... { path: 'login', component: LoginComponent }, { path: 'protected', component: ProtectedComponent, canActivate: [ LoggedInGuard ] },...providers: [...]
Nested Routes 层叠路由 p264 p287
层叠路由是包含其他路由
主路由->子路由
适用于:网站需要根据每一个用户单独显示对应的信息时。
见开篇路由配置
{ path: 'products', component: ProductsComponent, children: childRoutes }
products有子参数,
那么在products.module.ts组件中,可以定于自己的路由
export const routes: Routes = [{ path: '', redirectTo: 'main', pathMatch: 'full' },{ path: 'main', component: MainComponent },{ path: 'more-info', component: MoreInfoComponent },]
在组件中
goToProduct(id: string): void { this.router.navigate(['./', id], {relativeTo: this.route}); }
- Angular 中间部分 2.3 路由
- Angular 中间部分 2.1 内置指令和表单
- Angular 中间部分 2.2 依赖注入和Http
- angular 路由
- angular路由
- Angular路由
- angular 路由
- Angular路由
- angular路由
- angular路由
- angular路由
- Angular路由
- angular路由
- angular 路由
- Angular路由
- Angular 路由
- Angular路由
- angular 路由
- Eclipse+pydev 常用快捷键
- 使用Java实现基本排序
- 实用Map工具类
- xheditor编辑器
- js Dom
- Angular 中间部分 2.3 路由
- kobject,kset,子系统层次结构 、platform_device platform_driver
- 解决:Command `npm install --save --save-exact react-native` failed.
- JS之ActiveXObject对象使用整理
- DeleteFile删除失败错误码5
- WPF实现弧形旋转轮播图
- 一个基于ES5的vue小demo
- 使用cmake构建工程
- HDU1015