4

我有一个Angular 2项目,我想做以下事情:

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

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

  1. 不带参数导航到我的组件
  2. 设置查询参数ObservableNgOnInit并在收到第一个参数后重新加载 url 以设置默认参数
  3. 每次参数更改时导航到当前路线。这将更改参数,因此查询参数Observable将发出事件。Ajax然后将触发一个新的呼叫。

现在这可能不是最好的主意,但我遇到的问题如下: 1. 第一次Ajax触发两个呼叫 2. 如果我点击页面上的“当前路线”链接NgOnInit不会触发,所以我无法替换地址栏默认参数。

代码的简短版本如下(我故意省略了导入/@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}
    );
  }

}
4

1 回答 1

3

我做了类似的事情,但不订阅 queryParams。相反,我从构造函数中的路由快照评估它们并将数据提供给我的内部可观察对象,因此视图可以显示 queryParams 所说的任何内容。

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

于 2017-02-28T11:40:52.317 回答