Angular6更新查询参数而无需路由

时间:2018-09-07 15:23:44

标签: angular typescript

我正在研究的项目有很多带有搜索,排序和分页的列表。我完全能够使用这些条件(搜索,排序,分页)从API提取数据。

但是,我被要求做一个“共享链接”,以便用户可以在两者之间共享他们的查询列表。如果用户A的列表按“客户”排序,并在第5页上发送链接到用户B,则他或她将在第5页上按“客户”排序打开相同的列表。很简单。

我有一个可行的解决方案。我在ActiveRoute上订阅queryParams,解析这些参数,然后重新加载列表。请参见下面的代码。

组件模板html:

<ngb-pagination [collectionSize]="size" [page]="page" (pageChange)="changePage" >
</ngb-pagination>
<pre>Current page: {{page}}</pre>

组件打字稿:

ngOnInit() {

    this.route
      .queryParams
      .subscribe(queryParams => {

          this.sort = queryParams['sort'];
          this.search = queryParams['search'];
          this.page= +queryParams['page'] || 1;

          this.refresh();
    });

    this.refresh();
}

refresh() : void {

    this.transactionsService.fetch({
      from: (this.page - 1) * this.size,
      take: this.size,
      search: this.search,
      sort: this.sort
    }).subscribe(data => {

      this.entities = data.entities;

      this.total_size = data.total;
    });

}

changePage(event: number) : void {

    this.router.navigate(['/transactions'], { 
      queryParams : { page: event},
      queryParamsHandling: 'merge'
    });
  }

但是,我认为这是一个肮脏的解决方案,尤其是任何操作都是通过路由器处理的。我想首先避免在ngOnInit中订阅,然后以这种方式更新changePage函数:

 changePage(event: number) : void {

    this.page = event;

    this.refresh();

    // update query params without triggering navigation
    this.route.queryParams['page'] = this.page; ??????
  }'

这怎么可能?

1 个答案:

答案 0 :(得分:1)

您可以使用location提供程序来代替导航

import { ActivatedRoute, Router } from '@angular/router';  
import { Location } from '@angular/common';

...
constructor(
    private router: Router,
    private location: Location,
    private activatedRoute: ActivatedRoute,
    ...
)

changePage(event: number) : void {
  ...       
  this.location.go(`${this.activatedRoute.url}?page=${event}` );
  ...
}

this.location.go在这种情况下不会刷新窗口。

动态创建URL的方式:

const urlTree = this.router.createUrlTree([], {
    queryParams: { page: event },
    queryParamsHandling: 'merge'
    preserveFragment: true 
});

this.location.go(urlTree)

但是您可以将订阅保留在ngOnInit挂钩中,没关系。 为了防止路由器更新browser history,您必须传递replaceUrl: true参数

this.router.navigate([], { 
  relativeTo: this.activatedRoute, 
  queryParams: 
  {
      page: event
  },
  replaceUrl: true,
});

在不强制配置onSameUrlNavigation: 'reload'的情况下,角路由器将始终不会刷新您的页面,可以按原样保留解决方案