Angular2:路由到同一页面并更改查询参数

时间:2016-11-05 09:27:37

标签: angular angular2-routing angular2-router

我有一个Angular 2项目,我想要执行以下操作:

假设我有一个Component,它有一个支持分页和排序的数据表。 我想要实现的是每次表页面/大小和排序发生变化时,也要更改URL Parameters

但是,当我从Router访问特定组件时,我还想在Address Bar上设置默认网址参数 所以我想到的顺序如下:

  1. 导航到我的没有参数的组件
  2. Observable上设置查询参数NgOnInit并收到第一个参数 再次重新加载网址以设置默认网址
  3. 每次参数更改导航到当前路线。这将更改参数,以便查询参数Observable将发出事件。然后会触发新的Ajax来电。
  4. 现在这可能不是最好的主意,但我遇到的问题如下: 1.第一次触发两个Ajax次呼叫 2.如果我点击页面上的“当前路由”链接NgOnInit没有触发,那么我无法在地址栏中替换默认参数。

    以下代码的简短版本(我故意省略了import / @ Component注释等):

    export class MyComponent implements OnInit, OnDestroy {
    
      private params = {page: 0, size: 5}
      private activatedRoute: ActivatedRoute;
      private router: Router;
      private data = []
    
      private pageLoaded = false;
      private queryParamsSubscription = new Subscription();
    
      constructor(
        private router: Router, 
        private activatedRoute: ActivatedRoute
        private http: Http) {}
    
        ngOnInit(): void {
          this.queryParamsSubscription = this.activatedRoute.queryParams
            .debounceTime(100)
            .switchMap((routeParams) => {
              //assign the Url Parameters to my params object
              this.params = Object.keys(routeParams)
                .reduce((params, key) => {
                  params[key] = routeParams[key];
                  return params
                }, this.params);
              if(!this.pageLoaded) {
                //if the page is not leaded yet run reloadRoute and only replace 
                //the url (true flag) without adding to browser history
                //this will only run once
                this.reloadRoute(true);
                this.pageLoaded = true;
              }
              //finally perform the ajax call with the new params
              //so basically whenever the url parameters change
              //then fire an ajax call
              return this.findAll(this.params)
            })
            .subscribe((data) => {
                this.data = data;
              }
            );
      }
    
      //request data from the server
      findAll(params: any) {
        let urlParams: : URLSearchParams = //create urlParams from param
        return this.http.get(this.baseUrl, new RequestOptions({search: urlParams}))
         .map((res: Response) => res.json())
         .catch(err => {
           console.error(err);
           return Observable.from(err);
         })
      }
    
      ngOnDestroy(): void {
        this.queryParamsSubscription.unsubscribe();
      }
    
      onChangePageSize(size) {
        this.params['size'] = page.size
      }
    
      onChangePage(page) {
        this.params['page'] = page.page - 1;
        this.reloadRoute();
      }
    
      //this basically is called every time a parameter changes
      //so I navigate to the same page with the new parameters
      private reloadRoute(replaceUrl: boolean = false) {
    
        this.router.navigate(
          [this.activatedRoute.routeConfig.path], 
          {queryParams: params, replaceUrl: replaceUrl}
        );
      }
    
    }
    

1 个答案:

答案 0 :(得分:2)

我做了类似的事情,但没有订阅queryParams。相反,我从构造函数中的route-snapshot评估它们,并使用数据提供我的内部observable,因此视图可以显示queryParams所说的任何内容。

当用户移动到"下一页"时,我只是用新的偏移量提供我的observable(结果视图自动更新)并使用新的queryParams导航到同一页面,如果它们不同于最后一个queryParams(=>没有页面重新加载,没有触发queryParams,没有额外的http请求)。