angular+ 路由学习(三)路由带参

  • 如果是和我一样的小白,直接学习官文上的路由和导航的;在里程碑3:英雄特征区开始的,其中前几步是让我们把服务的部分代码拿过来;然后更改代码和目录结构,直接看后面总结代码,因为中间省略了很多;按照步骤来是很坑的;大佬请忽略;)
  • 进入正题之前,先了解到--已知用户场景是;首页为数据列表,点击其中任意可以跳转到对应数据的详情页,点击详情页的回退可以返回数据列表页面,同时数据列表页面被该数据是为选中的数据,样式有所更改;
  • 第一步,配置路由,这里将hero-detail作为需要传递参数的组件模块;(步骤可更换,理解就可以)
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';

const heroesRoutes: Routes = [
  {path: 'heroes', component: HeroListComponent},
  {path: 'hero/:id', component: HeroDetailComponent} // 路由带参; hero为路径   /:id 为占位参数,即这里是将传来动态参数id;如localhost:4200/hero/1;即访问id为1的数据;
];

@NgModule({
  imports: [RouterModule.forChild(heroesRoutes)],
  exports: [RouterModule]
})
export class HeroesRoutingModule { }

 

  • 第二步,显示hero-list的列表数据
  • <h2>Heroes</h2>
    <ul class="heroes">
      <li *ngFor="let hero of heroes$ | async"
        [class.selected]="hero.id === selectedId">
        <!-- 视图带参跳转 -->
        <a [routerLink]="['/hero', hero.id]">
          <span class="badge">{{hero.id}}</span> {{hero.name}}
        </a>
        <!-- <a routerLink="/hero/{{hero.id}}">
          <span class="badge">{{hero.id}}</span> {{hero.name}}
        </a> -->
      </li>
    </ul>
    <button routerLink="/sidekicks">Go to sidekicks</button>
    import { Observable } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Router } from '@angular/router';
    
    import { Hero } from '../hero';
    import { HeroService } from '../hero.service';
    
    @Component({
      selector: 'app-hero-list',
      templateUrl: './hero-list.component.html',
      styleUrls: ['./hero-list.component.css']
    })
    export class HeroListComponent implements OnInit {
      heroes$: Observable<Hero[]>;
      selectedId: number;
      heroes: Hero[];
      constructor(
        private heroService: HeroService,
        private activatedRoute: ActivatedRoute,
        private router: Router
        ) { }
    
      ngOnInit() {
        this.getHeroList();
        // this.heroes$ = this.heroService.getHeroes();
      }
      getHeroList(){
       // activatedRoute.paramMap 属性是一个路由参数的可观察对象; 当导航到这个组件时,paramMap会将获取对应id;并订阅相关值;设置到selectedId;
       this.heroes$ =  this.activatedRoute.paramMap.pipe(
        switchMap(params => {
          this.selectedId = +params.get('id'); // + 将字符串转化成数字类型 ;接收从详情页传递来的id 值进行回退选中的显示
          return this.heroService.getHeroes(); // 获取列表数据
        })
      );
      // 通过subscribe()订阅返回
      // this.heroService.getHeroes().subscribe(item => this.heroes = item);
      // console.log(this.heroes);
      }
      // 跳转方法
     goDetailById(heroId){
       this.router.navigate(['hero', heroId]); // 路由跳转;
        // this.router.navigate(['hero',{ id: heroId, flag: true}]); // 多个参数
      }
    }

     

  • 第三步,处理传递到hero-detail的路由参数
  • <h2>HEROES</h2>
    <div *ngIf="hero$ | async as hero">
      <h3>"{{ hero.name }}"</h3>
      <div>
        <label>Id: </label>{{ hero.id }}</div>
      <div>
        <label>Name: </label>
        <input [(ngModel)]="hero.name" placeholder="name"/>
      </div>
      <p>
        <button (click)="gotoHeroes(hero)">Back</button>
      </p>
    </div>
    import { switchMap } from 'rxjs/operators';
    import { Component, OnInit, Input } from '@angular/core';
    import { Router, ActivatedRoute, ParamMap } from '@angular/router'; // 导入类
    import { Observable } from 'rxjs';
    
    
    
    import { Hero } from '../hero';
    import { HeroService } from '../hero.service';
    
    
    @Component({
      selector: 'app-hero-detail',
      templateUrl: './hero-detail.component.html',
      styleUrls: ['./hero-detail.component.css']
    })
    export class HeroDetailComponent implements OnInit {
    
      hero$: Observable<Hero>; //声明
      // 服务注入
      constructor(
        private router: Router,
        private activatedRoute: ActivatedRoute,
        private heroService: HeroService
      ) { }
    
      ngOnInit() {
        // ActivatedRoute服务来处理路由的路径和参数;这里接收路由参数ID,获取关联数据
        // paramMap; 一个Observable, 包含当前路由的必要参数和可选参数组成的map对象;当这个map值变化,可以使用get(name)获取id参数;然后HeroService获取相关id对应的数据并返回;
        // switchMap(); 可以取消以前未完成的请求,即发起新ID获取请求时,而service还在接收之前id对应的数据时,switchMap 可以放弃老请求而返回新id 的请求数据;
        this.hero$ = this.activatedRoute.paramMap.pipe( 
          switchMap((params: ParamMap) =>
            this.heroService.getHero(params.get('id')))
        );
    
      }
      gotoHeroes(hero: Hero) {
        let heroId = hero ? hero.id : null;
        this.router.navigate(['heroes', { id: heroId, foo: 'foo' }]); // 路由跳转;
      }
    
    }

     

  • hero.service.ts中需要更改
  • import { Injectable } from '@angular/core';
    
    import { Observable, of } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    import { Hero } from './hero';
    import { HEROES } from './mock-heroes';
    
    
    @Injectable({
      providedIn: 'root',
    })
    export class HeroService {
    
      constructor() { }
    
      getHeroes(): Observable<Hero[]> { // 获取列表数据
        // TODO: send the message _after_ fetching the heroes
        return of(HEROES);
      }
      getHero(id: number | string) { // 获取指定id数据
        return this.getHeroes().pipe(
          map((heroes: Hero[]) => heroes.find(hero => hero.id === +id))
        );
      }
    }

     

  • 最后,官文坑点;

 

  • 虽然下面有解释到部分更改和步骤,但是一步一步操作和最后给出的代码是有些偏差的;导致我这种小白边做边敲代码,发现结果对不上;后来是对着代码往回推,才了解到的;虽然官方文档上有最后的代码,但是我还是重新码了出来,以提高熟练度;

 

posted @ 2019-07-27 14:22  抹茶奶盖xh  阅读(394)  评论(0编辑  收藏  举报