網站搜尋

angular - 在不進行路由的情況下更新 Angular6 的查詢參數


我正在進行的項目有很多帶有搜尋、排序和分頁的列表。我完全能夠使用這些條件(搜尋、排序、分頁)從 API 獲取數據。

然而,我被要求製作一個「可分享的連結」,讓使用者可以互相分享他們查詢的清單。如果使用者 A 的清單依「客戶」排序並且在第 5 頁,將連結發送給使用者 B,他或她將在第 5 頁看到依「客戶」排序的同一清單。很簡單。

我有一個可行的解決方案。我訂閱 ActiveRoute 上的 queryParams,解析這些參數然後重新加載列表。請看下面的代碼。

元件範本 HTML:

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

元件 TypeScript:

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

你可以使用 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 鉤子中,這沒問題。為了防止路由器更新 瀏覽器歷史記錄,你必須傳遞 replaceUrl: true 參數

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

如果不強制使用 onSameUrlNavigation: 'reload' 配置,Angular 路由器無論如何都不會刷新你的頁面,你可以保持你的解決方案不變