关于angular:ActivatedRoute-和-Router以及记录后台遇到的问题

6次阅读

共计 4229 个字符,预计需要花费 11 分钟才能阅读完成。

ActivatedRoute 和 Router 的区别

前台 angular 应用这两个来进行路由的操作,然而如同始终不大清楚区别。这里简略记录一下。

区别

  • ActivatedRoute 是以后组件的路由对象,蕴含了以后的路由信息。
  • router 是全局路由器对象。能够在各个路由之间跳转

所以最大的区别我认为就是作用域不同,一个是在获取以后路由的信息,另一个则是对全局路由操作跳转。

ActivatedRoute:

将 ActivatedRoute 在 ngOnit 中打印之后,能够看到有如下属性。
component, date , fragment,params,queryParams,snapshot,url,_futurnSnapshot
_routerState 等。

Angular 文档将 ActivatedRoute 定义为。提供给每个路由组件的服务,其中蕴含路由特定信息,例如路由参数、静态数据、解析数据、全局查问参数和全局片段。每个都 Route 将一个 URL 映射 path 到一个组件。


这里讲一下常看到或者用到的几个属性:

component

咱们能够看到对应的是 IndexComponet, 也就是以后路由对象对应着的是 IndexCompoent.

snapshot

在 Snapshot 中,咱们在组件和路由中的值是不同步的。如果应用 snapshot 并且在路由定义中有一个参数,例如 product/:id,那么如果页面更改了 id,那么将不会取得任何新的 id。快照意味着它是在 ngOnInit 运行时,这是它在那个工夫点的状态。

咱们能够通过如下的形式获取 snapshot 快照,并能够获取它的 params 路由参数。

constructor(private route: ActivatedRoute){
} 
ngOnInit() {const id = this.route.snapshot.params.id;}

这里 params 和 queryParams 用的比拟多,所以重点讲一下。

params 路由参数

params 生成的 URL 采纳 matrix 法(;key=value;kye1=value1)

Angular 路由器应用它来确定路由。它们是路由定义的一部分。咱们须要 product/:id 这种模式来跳转到正确的路由。

咱们常应用这样的模式,当如下定义路由时,id 就是 params 参数

{path: 'product/:id', component: ProductDetailComponent}

获取 id 就是 params 参数:

constructor(private route:ActivatedRoute){
}
 
this.route.params.subscribe(param => {const id = +param.id;});

queryParams 查问参数

queryParams 生成的 URL 采纳传统表示法(?key=value&key1=value1)

queryParams 查问参数是可选的,通常会以 /product?page=10 的模式传递。

传递查问参数:
第一种是通过 [queryParams] 指令增加。

<a [routerLink]="['product']" [queryParams]="{page:10}">Page 10</a>

第二种应用 navigate 形式导航增加。

  this.router.navigate(['/product'], {queryParams: { page: 10} }); 

读取查问参数:

constructor(private route:ActivatedRoute){
}
 
this.route.queryParams.subscribe(param => {const page = +params['page'];
});

Params 和 queryParams 总结

两种都有不同的用法:

当咱们心愿依据 productID 辨认产品,在这种状况下,能够应用 Params 参数。

获取 /product/{id}

再举一个例子,您想依据指定过滤产品,在这种状况下,能够应用 queryParams 参数。

GET /product?colour=red

我的项目中采取了这样的形式:

订阅了 params 参数。

public subscribeParams(): void {this.route.params.subscribe((params: {page?: string, size?: string}) => {this.params = params;});
  }

在路由跳转的时候,将参数转换为路由参数。


onSubmit(queryForm: FormGroup) {this.params = {...this.params, ...queryForm.value}
    this.reload(this.params);
}

reload(params: Params): void {
    // 将参数转换为路由参数
    const queryParams = CommonService.convertToRouteParams(params);
    this.router.navigate(['./'],
      {
        relativeTo: this.route,
        queryParams: queryParams,
      }).then();}

这样使得路由显示的是 matrix 法,比拟好看。也对立了参数获取形式。


Router

它加载与所申请路由相关联的组件,以及获取特定路由的相干数据。这容许咱们通过管制不同的路由,获取不同的数据,从而渲染不同的页面.

简略来说就是跳转页面。

它依据咱们提供的路由来跳转,如下。咱们须要把这个 TaskRoutingModule 引入所处的组件,以后组件跳转到时候,就能依据提供的门路来跳转到相应的组件


const routes: Routes = [
  {
    path: '',
    component: IndexComponent,
  },{
    path: 'view/:id',
    component: ViewComponent,
  }
];

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

跳转形式:

第一种形式能够应用 routerLink 指令跳转。

  <a routerLink="view/{{id}}">view 页面 </a>

第二种形式能够应用 navigate 办法进行相对路径跳转

this.router.navigate(['./'],
      {
        relativeTo: this.route,
        queryParams: queryParams,
      }).then();

也能够应用 navigateByUrl 办法进行绝对路径跳转

 this.router.navigateByUrl('volunteer').then();

总结:当咱们须要获取路由的信息的时候,能够应用 activatedRoute, 当须要应用路由跳转,应用 Router。

后盾遇到的问题

另外说一下之前遇到的问题。

以后台向后盾传值的时候,后盾没有接管到如图的 name。

前面排查起因的时候,才发现前台传的是字段名是 content,而不是 name。并没有与后盾的字段名对应。

@RequestParam

@RequestParam 注解,等价于 request.getParam,能够解决前台参数名称与后盾接管参数变量名称不统一的问题。

RequestParam: 次要用在 Controller 层,用于获取 URL 中“?”后携带的参数的值, 如:
http://localhost:8080/request… 中 id 参数的值

  • 相干属性:
  • 1、name/value:url 中指定参数的名称
  • 2、required: 为 true 时, 这个参数必选填写, 默认是 true, 为 false 时: 参数可选是否填写
  • 3、defaultValue:参数不填写时的默认值

所以以后后盾参数不统一的时候咱们能够应用

RequestParam(value="前端传值的字段")<T> 后端要求的字段名)

尽管这种形式能够解决,然而前后台参数统一比拟标准,所以我改了前台传递的的字段名。

获取认证为 null

@Override
  public Optional<AuthUserDetails> getAuthUserDetailWithoutTransaction() {logger.debug("依据认证获取以后登录用户名,并获取该用户");
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
}

打印了下 SecurityContextHolder.getContext().getAuthentication()后果为 null。

查阅了 Baeldunghttps://www.baeldung.com/spri…

得悉
默认状况下,Spring Security Authentication 绑定到 ThreadLocal(也就是线程本地.)因而,当执行流在带有 @Async 的新线程中运行时,它不会是通过身份验证的上下文,会失落掉上下文信息。

解决办法

1. 能够传递上下文信息:

    // 1. 在主线程中获取平安上下文。SecurityContext securityContext = SecurityContextHolder.getContext();
    threadTaskExecutor.execute(() -> {
        try {
            // 2. 将主线程中的平安上下文设置到子线程中的 ThreadLocal 中。SecurityContextHolder.setContext(securityContext);
            // 业务代码
        } catch (Exception e) {// 异样信息捕捉} finally {
            // 革除操作
            // 3. 将调用者中的平安上下文设置到以后业务子线程中的 ThreadLocal 中。SecurityContextHolder.clearContext();}
    });

具体:https://blog.csdn.net/qq_3725…。

2. 在主线程中获取好须要的信息再作为参数传递到异步办法中

这个办法也是最简略的办法,在异步办法的上一层依据上下文获取好想要的信息之后,比方 id 等,再作为参数传递到异步办法。

当然还有很多办法,能够谷歌搜寻关键字 异步平安上下文配置

正文完
 0