angular路由参数路由跳转

2023-11-15

路由参数及跳转

本节介绍路由参数及跳转相关。

准备工作

首先,我们需要将上一节的 CommentServiceUserService抽离成单独的文件,以便多处使用。

ng g s components/router-study/comment/comment
ng g s components/router-study/user/user

复制上节代码到对应文件:

// comment.service.ts
@Injectable()
export class CommentService {
  constructor() { }
  getComments(): Observable<Comment[]> {
    return of(COMMENTS);
  }
  // 根据Id匹配数据
  getComment(id: number | string): Observable<Comment> {
    return this.getComments().pipe(
      map((comments: Comment[]) => comments.find(comment => comment.id === +id))
    );
  }
}

需求分析

  1. 点击每条评论跳转评论详情页面;

  2. 详情页返回列表页时,高亮显示点击后的评论。

我们将通过页面链接点击事件两种方式来实现上述需求。

创建 comment组件(注:已将上节创建的评论列表组件 comment.component改为 comments.component):

创建详情组件

ng g c components/router-study/comment/comment --flat -t -s -c OnPush

tips: --flat参数表示直接在comment文件夹下面创建组件,不将文件放在单独的文件夹中。

在这里插入图片描述

配置路由:

// router-study-routing.module.ts
{path: 'comment/:id', component: CommentComponent}

在这里插入图片描述

routerLink

语法: routerLink: string | any[]

上节我们通过添加 routerLink属性实现了组件之间的跳转:

<a class="nav-link" routerLink="/comments" routerLinkActive="active">Comments</a>

按照这个思路,我们来试一下直接在字符串后面添加 id:

// comments.component.ts
template: `
    <h3>Comment page</h3>
    <ul class="list-group">
      <li
        class="list-group-item"
        [class.active]="item.id === selectedId"
        *ngFor="let item of comments$ | async"
        (click)="onSelected(item.id)"
        [routerLink]="'/comment/' + item.id"
      >
        {{ item.name }}
      </li>
    </ul>
  `,

不出意外,这样果然行得通。那 routerLink的值是数组呢?

[routerLink]="['/comment', item.id]"

页面将会渲染成这样:

在这里插入图片描述

点击之后,一样可以实现跳转。我们可以得出下面结论:

  • 绑定数组时,会拼接数组的每一项,且中间用’/‘分割

获取详情数据

首先应该获取到urlid参数,这里我们就要用到 ActivatedRoute这个接口。

ActivatedRoute:

在这里插入图片描述

从上图可以看出,我们至少可以使用跟 params有关的属性,他们都是 Observable类型。

constructor中注入:

// comment.component.ts
constructor(private route: ActivatedRoute) { }

params

打印 paramsparamMap:

this.route.params.subscribe(res => console.log(res));  
this.route.paramMap.subscribe(res => console.log(res)); 

在这里插入图片描述

这样就能获得传入的 id值,从而获取详情:

// comment.component.ts
export class CommentComponent implements OnInit {
  comment$: Observable<Comment>;
  constructor(private route: ActivatedRoute, private commentServer: CommentService) { }

  ngOnInit(): void {
    // 使用params获取id
    // this.comment$ = this.route.params.pipe(
    //   switchMap( params => this.commentServer.getComment(params.id))
    // );

    // 使用paramMap获取id
    this.comment$ = this.route.paramMap.pipe(
      switchMap(paramMap => this.commentServer.getComment(paramMap.get('id')))
    );
  }
}

Map类型的数据需要使用 get()获取。

渲染数据:

<div class="card" style="width: 18rem;">
  <div class="card-body" *ngIf="comment$ | async as comment; else noneComment">
    <h5 class="card-title">{{comment.name}}</h5>
    <h6 class="card-subtitle mb-2 text-muted">{{comment.email}}</h6>
    <p class="card-text">{{comment.body}}</p>
    <hr>
    <button class="btn btn-primary" routerLink="/comments">返回</button>
  </div>
</div>
<ng-template #noneComment>没有comment内容</ng-template>

在这里插入图片描述

上面已经实现基础功能,但是返回的时候并没有高亮上次选择的数据。我们来解决这个问题。

在列表页面要知道上次选择的数据,我们需要将当前 id回传。可以用上面介绍的方式,很容易就能做到。但是,这里我们换一种方式传递参数:

<button class="btn btn-primary" [routerLink]="['/comments', {id: comment.id}]">返回</button>

返回列表页面时,URL地址变成了这样的格式: http://localhost:4200/comments;id=4。 使用分号 “;” 间隔了参数。

同样,我们可以通过 paramsparamMap获取到 id:

// comments.component.ts
ngOnInit(): void {
    this.comments$ = this.route.params.pipe(
      switchMap(params => {
        this.selectedId = +params.id;
        return this.commentServer.getComments();
      })
    );
    // 或者这样:
    // this.comments$ = this.route.paramMap.pipe(
    //   switchMap(paramsMap => {
    //     this.selectedId = +paramsMap.get('id');
    //     return this.commentServer.getComments();
    //   })
    // );
  }

queryParams

前面不是还有个 queryParamsqueryParamMap一直没用吗? 既然是 query开头的属性,那URL中连接参数的分隔符必然是“?”。所以,那就试试吧~

一开始,我试图用字符串拼接的方式传递 query参数:

[routerLink]="'/comments?id=' + comment.id"

URL会转译成这样: http://localhost:4200/comments%3Fid%3D3,导致错误。所以,我们需要另一个输入性属性 queryParams

<button class="btn btn-primary" routerLink="/comments" [queryParams]="{id: comment.id}">返回</button>

跳转成功,并能够打印出 query参数:

在这里插入图片描述

snapshot

除了上面两种方式能够获取到 URL中的参数,我们还可以使用 snapshot

当我们的 URL是这样的格式: http://localhost:4200/comment/2?id=a

打印 snapshot

console.log(this.route.snapshot);

在这里插入图片描述

这样,我们可以同时拿到所需要的 paramsqueryParams,操作简单很多。

编程式跳转

除了上面介绍的用 routerLink进行跳转,我们还可以使用编程式的跳转。

Router

一个提供导航和操纵 URL能力的 NgModule

在这里插入图片描述

单纯从事件名看来,我们应该可以使用 navigateByUrl()navigate()进行跳转:

navigateByUrl()

语法:navigateByUrl(url: string | UrlTree, extras: NavigationBehaviorOptions): Promise<boolean>

interface UrlTree {
  root: UrlSegmentGroup
  queryParams: Params
  fragment: string | null
  queryParamMap: ParamMap
  toString(): string
}

先来个简单的例子:

<h3>Comment page</h3>
<ul class="list-group">
  <li
    class="list-group-item"
    [class.active]="item.id === selectedId"
    *ngFor="let item of comments$ | async"
    (click)="toComment(item.id)"
  >
    {{ item.name }}
  </li>
</ul>

navigateByUrl()是基于所提供的 URL进行导航,*** 必须使用绝对路径 ***。

// comments.component.ts
toComment(id: number): void {
  this.router.navigateByUrl('/comment/' + id).then(r => console.log(r));
}

传递 query参数:

goBack(id: number) {
  this.router.navigateByUrl('/comments?id=' + id)
}

navigate()

语法:navigate(commands: any[], extras: NavigationExtras = { skipLocationChange: false }): Promise<boolean>

导航到相对于当前 URL的动态路由路径:

// comments.component.ts
toComment(id: number): void {
  this.router.navigate(['/comment', id]).then(r => console.log(r));
}

传递 query参数:

goBack(id: number) {
  this.router.navigate(['comments'], {queryParams: {id}}).then(r => console.log(r));
}

总结

  1. 可以使用 routerLink及函数式用方法进行跳转;

  2. 两种方式传递 query参数都需要使用 queryParams

  3. 使用 ActivatedRoute.snapshot能够快速获得路由此刻的一系列信息。

欢迎关注我的公众号,公众号将第一时间更新angular教程:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

angular路由参数路由跳转 的相关文章

  • 在特定页面上执行 javascript 的正确“Rails”方式

    我试图在特定页面上运行 javascript 而我唯一的解决方案似乎是反模式 我有controller js内部生成的assets javascripts 我在用着gem jquery turbolinks 我的代码类似于以下内容 docu
  • 在 Internet Explorer 中使用什么来监视 jscript 内存使用情况

    我们正在调试 GWT 应用程序 在 Firefox 中运行正常 在 IE6 0 中开始运行正常 但一段时间后 它就会崩溃并开始爬行 经过一些测试后 我们怀疑存在一些内存问题 使用了太多内存 内存泄漏等 除了使用taskmanager和pro
  • 从函数返回函数的目的是什么?

    阅读一些遗留代码 发现 A prototype setSize function var v1 new Vector2 return function size var halfSize v1 copy size multiplyScala
  • Vue 3 Composition API 提供/注入在单文件组件中不起作用

    我正在使用 Composition API 在 VueJS 3 中创建一个库 我实现了提供 注入 如中所述docs https v3 vuejs org guide composition api provide inject html i
  • 如何正确清理来自 AngularJS 控制器的无效输入的表单?

    我有一个 AngularJS 表单 其中包含 除其他字段之外 类型之一url 后者很重要 因为这会强制相应的输入成为有效的 URL 在某些条件下 例如 要关闭具有此类表单的模式对话框 我想以编程方式清除该表单 为此 我实现了方法reset基
  • 在哪里存储角度中的 JWT 令牌?

    我正在使用 Django 和 Angular 构建一个应用程序 目前 我正在本地存储上存储后端发出的 JWT 但是 我担心 XSS 攻击 我应该使用仅 HTTP 的 cookie 来存储令牌吗 我还考虑将令牌存储在我的身份验证服务类中的变量
  • 是否可以在 Angular Material Tooltip 中包含一个列表?

    基本上我想在我的工具提示中有一个 ul 元素 我正在使用 Angular 5 以及 Angular 5 的兼容材质 帕维尔 阿加科夫 Pavel Agarkov 的评论方向是正确的 为了让事情变得简单 创建一个自定义管道来自动将文本转换为项
  • javascript 选择自定义光标 (svg)

    我正在动态地将光标更改为悬停时的本地 svg element on mouseover function this css cursor url svgs pointer svg 9 30 auto 工作正常 但我想选择该 svg 来操纵其
  • JavaScript 继承;调用和原型

    要在Javascript中实现继承 通常需要执行以下两个步骤 假设我有一个基类 Animal var Animal function name this name name 我现在想从中派生一个子类 Dog 所以我想说 var Dog fu
  • React Router v4 不渲染组件

    React Router v4 渲染组件存在问题 在应用程序初始加载时 它将呈现与 URL 相对应的正确组件 但是 任何后续的组件Link单击不会呈现所需的组件 图书馆 反应路由器 4 2 2 https reacttraining com
  • JavaScript RegEx:不同的结果:使用字符串和使用正则表达式“文字”构建模式?

    使用 RegExp 文字与字符串之间有什么区别吗 http jsfiddle net yMMrk http jsfiddle net yMMrk String prototype lastIndexOf function pattern p
  • 如何正确取消引用然后删除 JavaScript 对象?

    我想知道从内存中完全取消引用 JavaScript 对象的正确方法 确保删除时不会在内存中悬空 并且垃圾收集器会删除该对象 当我看这个问题时在 JavaScript 中删除对象 https stackoverflow com questio
  • LeafleteachLayer函数不会迭代所有Layer

    使用 GeoJSON 数据数组创建一些标记 getJSON GetLocationsServlet function data L geoJSON data onEachFeature onEachFeature addTo mymap G
  • JavaScript eval("{}") 返回行为?

    根据ECMA 262 规范 http www ecma international org publications files ECMA ST Ecma 262 pdf 以下语句返回1 eval 1 eval 1 eval 1 var a
  • Google Maps API (v3) 添加/更新标记

    编辑 它现在可以工作 但如果用户不允许或没有基于位置的服务 则不会加载 请参阅 jsfiddle 示例接受的答案评论 我已经浏览了一些教程和问题 但我无法安静地理解正在发生的事情 或者在这种情况下 没有发生 当用户单击链接时 我正在加载地图
  • Highcharts jQuery 渲染问题 - 所有浏览器

    我在尝试使用构建堆积柱形图时遇到了一个奇怪的问题高图表 http www highcharts com 当图表呈现时 在您调整浏览器大小之前 不会显示列无论如何 导致图表重绘 我认为 图表的其余部分显示 轴 标题等 但不显示列本身 我在 I
  • 使用 next.js 进行服务器端渲染与传统 SSR

    我非常习惯 SSR 意味着页面得到完全刷新并从服务器接收完整 HTML 的方法 其中根据后端堆栈使用 razor pub other 进行渲染 因此 每次用户单击导航链接时 它只会向服务器发送请求 整个页面将刷新 接收新的 HTML 这就是
  • 什么是 WKWebView 中的 WKErrorDomain 错误 4

    fatal error LPWebView encounters an error Error Domain WKErrorDomain Code 4 A JavaScript exception occurred UserInfo 0x7
  • 如何通过索引访问 JSON 对象中的字段

    我知道这不是最好的方法 但我别无选择 我必须通过索引访问 JSONObject 中的项目 访问对象的标准方法是只写this objectName or this objectName 我还找到了一种获取 json 对象内所有字段的方法 fo
  • 测量窗口偏移

    有没有一种方法可以测量 jQuery 中窗口的偏移量 以便我可以比较 固定 元素和相对定位元素的位置 我需要能够知道窗口滚动了多远 以便我可以使用该图来计算固定元素的高度 相对于视口顶部 和相对对象的高度 相对于顶部 之间的差异文件的内容

随机推荐