zoukankan      html  css  js  c++  java
  • angular9的学习(五)

    通过路由导航传递参数

    this.router.navigateByUrl('/user', { state: { orderId: 1234 } });
    <a [routerLink]="/user" [state]="{ orderId: 1234 }">Go to user's detail</a>
    
    状态将保留在浏览器的hostory.state属性上
    在跳转到的页面上
    export class DyTwoComponent implements OnInit {
    
      constructor(private router:Router) {
        console.log(this.router.getCurrentNavigation().extras.state);
      }
    
      ngOnInit(): void {
        console.log(history.state);
      }
    
    }
    
    

    注意一个坑, 当你使用getCurrentNaviagation 的时候,你需要在constructor 中进行调用,不然调用不到,或者在ngOnInit 直接拿也可以

    记录快照

    我们从/ccc/1 导航到/ccc/123 需要记录当前数据变化

    export class DyTwoComponent implements OnInit {
      constructor(private r:ActivatedRoute) {
        r.url.subscribe((val)=>{
          console.log(val);
        })
      }
    }    
    

    Navigation修改导航策略

    可以理解成vue里面的编程式导航

    相对导航

      {
        path: 'two/:id',
        component: DyTwoComponent,
        children:[
          {
            path:'one',
            component:DyOneComponent
          },
          {
            path: 'ref',
            component: RefsComponent,
          }
        ]
      }
    
    假设当前路由是 /two
    <div (click)="clickDown('one')">跳one子路由</div>
    <div (click)="clickDown('ref')">跳ref子路由</div>
    
    export class DyTwoComponent implements OnInit {
      constructor(private router: Router, private r: ActivatedRoute) { }
      ngOnInit(): void {}
    
      clickDown(item: string) {
        this.router.navigate(['./' + item], {relativeTo: this.r})
          					'../' //那么会跳转到 /one  /ref 前面没有two
      }
    }
    跳转到 two/one
    跳转到 two/ref
    但是当 two/:id  是动态的跳转会报错,暂时不知道怎么解决
    

    加问号参数

    /results?page=1
    this.router.navigate(['/results'], { queryParams: { page: 1 } });
    

    设置URL的哈希片段

    /results#top
    this.router.navigate(['/results'], { fragment: 'top' });
    

    参数合并

    /results?page=1 to /view?page=1&page=2
    this.router.navigate(['/view'], { queryParams: { page: 2 },  queryParamsHandling: "merge" });
    

    保留URL片段用于下一次导航

    /results#top   /view#top
    this.router.navigate(['/view'], { preserveFragment: true });
    

    不会记录到历史记录

    this.router.navigate(['/view'], { skipLocationChange: true });
    

    替换当前的历史记录

    this.router.navigate(['/view'], { replaceUrl: true });
    

    重新刷新路由

    /pro/1 切换到/pro/1221
    
     clickDown() {
        this.router.navigateByUrl('/pro/1221');
        this.router.routeReuseStrategy.shouldReuseRoute = function(){
          return false;
        };
      }
    我们发现生命周期会重新执行
    

    Route

    定义单个路由的配置对象

    通配符

    无论你导航到何处,来执行实例化的组件

    [{
      path: '**',
      component: WildcardComponent
    }]
    

    重定向

    redirectTo

    空路径

    空路径会继承父级的参数和数据

    /team/12 实例化的是AllUsers 组件

    [{
      path: 'team/:id',
      component: Team,
      children: [{
        path: '',
        component: AllUsers
      }, {
        path: 'user/:name',
        component: User
      }]
    }]
    

    匹配策略

    前缀匹配
    /team/12/user   /team/:id 匹配
    
    {
      path: '',
      pathMatch: 'prefix', //default
      redirectTo: 'main'
    }
    
      pathMatch: 'full', 完整匹配
      { path: '', redirectTo: 'list', pathMatch: 'full' },
    

    路由守卫

    触发顺序:

    canload 加载

    canActivate 进入(重要)

    canActivateChild 进入子路由

    canDeactivate 离开(重要)

    我只能简要的实现以下

    创建一个服务

    import {Injectable} from '@angular/core';
    import {
      ActivatedRouteSnapshot,
      CanActivate,
      CanDeactivate,
      Router,
      RouterStateSnapshot
    } from "@angular/router";
    import {DyOneComponent} from "./dy-one/dy-one.component";
    
    @Injectable({
      providedIn: 'root'
    })
    export class AuthGuardService implements CanActivate, CanDeactivate<DyOneComponent> {
    
      constructor(private router: Router) {
      }
    
      // 进入
      canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        const url: string = state.url;
        console.log(url);
        return true;
      }
    
      // 离开
      canDeactivate(component:DyOneComponent,currentRoute:ActivatedRouteSnapshot,currentState:RouterStateSnapshot) {
    
        return window.confirm('是否离开这个模块')
      }
    
    }
    DyOneComponent 是你离开这个页面所在的组件
    

    路由

      {
            path: 'home',
            component: HomeComponent,
            canActivate: [AuthGuardService],// 进入
            canDeactivate:[AuthGuardService] // 离开
       }
    

    是否需要恢复之前滚动的位置ExtraOptions

    @NgModule({
      imports: [RouterModule.forRoot(routes,{ scrollPositionRestoration: 'enabled',})],
      exports: [RouterModule]
    })
    

    自定义滚动记录

      constructor(private router: Router, private viewportScroller: ViewportScroller) {
        this.router.events.pipe(
          filter((e: Scroll) => e instanceof Scroll)
        ).subscribe(
          e => {
            if (e.position) {
              // 后退
              viewportScroller.scrollToPosition(e.position);
            } else if (e.anchor) {
              // 哈希
              viewportScroller.scrollToAnchor(e.anchor);
            } else {
              // forward navigation
              viewportScroller.scrollToPosition([0, 0]);
            }
          }
        )
      }
    

    resolve

    resolve 保证了数据获取后在进行路由跳转,防止因为数据延迟而出现的空组件情况

    也可以应用resolve 来进行路由拦截

    总是写着有问题,没办法只要有一个不是很严谨的写法

    路由
       {
            path: 'two/:id',
            component: TwoComponent,
            resolve: {
              detail: BlockService // 这个是拦截的路由
            }
          },
              
    服务
    import {Injectable} from '@angular/core';
    import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from "@angular/router";
    import {Observable} from "rxjs";
    import {map} from "rxjs/operators";
    
    @Injectable()
    export class BlockService implements Resolve<any> {
      constructor(private router: Router) {
      }
      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): any {
        let ids = route.paramMap.get('id');
        return new Observable(subscriber => {
          subscriber.next(11)
        }).pipe(
          map(res => {
            if (res == ids) { //成功
              return res
            } else {// 失败
              this.router.navigate(['/three']);
              return false
            }
          })
        ).subscribe(val => {
          return val
        })
      }
    
    }
    成功后才会展示那个组件
    

    记得好好想想取消订阅, 我看官网上说不需要取消订阅,具体点还需要探究

  • 相关阅读:
    Codeforces 每日一练 1213G+961E+1282B2
    AtCoder Beginner Contest 161题解
    Codeforces每日一练 495B+55C+1280C
    CF1062E 线段树/LCA
    Codeforces Round #697 (Div. 3) 题解
    Codeforces Round #511 (Div. 2) A~D题解
    Atcoder ABC 189 题解
    CF1093G 高维曼哈顿距离/线段树
    CF1117D Magic Gems 矩阵快速幂 DP
    CF1106E Lunar New Year and Red Envelopes DP
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/12640305.html
Copyright © 2011-2022 走看看