在查询参数更改时,路由未更新

时间:2017-10-27 07:39:43

标签: angular routing query-parameters

在我的应用程序中,有多个链接,其中我有一些links具有相同的routequery parameters不同。

说,我有像:

这样的链接
.../deposits-withdrawals
.../deposits-withdrawals?id=1
.../deposits-withdrawals?id=2&num=12321344

当我在上述路线之一并且从上面提到的另一条路线本地时,路线不会改变。甚至没有调用ngOnInitngOnChanges等任何函数。我已将参数从queryParameters更改为matrixParameters,但没有成功。我经历了很多链接和答案。但是,他们都没有解决我的问题。帮帮我解决这个问题。

谢谢...

修改

<button routerLink="/deposits-withdrawals" [queryParams]="{ type: 'deposit' ,'productId': selectedBalance.ProductId}" class="wallet-btns">DEPOSIT {{selectedBalance.ProductSymbol}}</button>
<button routerLink="/deposits-withdrawals" [queryParams]="{ type: 'withdrawal' ,'productId': selectedBalance.ProductId }" class="wallet-btns">WITHDRAW {{selectedBalance.ProductSymbol}}</button>

4 个答案:

答案 0 :(得分:9)

我曾经遇到过这个问题。你能放一些代码,或者你试过的解决方案吗? 我会给你一些为我工作的东西,但你最好给我一些细节,以便我能提供帮助。 支持我们在这里: _some_url_ / deposit-withdrawals ,我们希望导航,只更改参数。

let url = "id=2&num=12321344"
this.router.navigate(['../', url], { relativeTo: this.route });

希望有所帮助:/

=================================== 编辑 ==== ==============================

您必须检测查询参数已更改。为此,您可以在组件的构造函数中为queryParameters changings添加一个侦听器。这可以通过这种方式使用路由器来完成:

constructor(route:ActivatedRoute) { 
    route.queryParams.subscribe(val => { 
        // put the code from ngOnInit here 
    }); 
}

添加此侦听器以检测查询参数更改,意味着您必须将代码从ngOnInit函数移动到此侦听器。每次,你导航,它都会被调用。

对于导航,您可以使用html导航或ts导航。如果你想要它是html,你可以使用:

<button routerLink="/deposits-withdrawals" [queryParams]="{ type: 'withdrawal' ,'productId': selectedBalance.ProductId }" class="wallet-btns">WITHDRAW {{selectedBalance.ProductSymbol}}</button>

答案 1 :(得分:1)

在更新查询参数时,必须重新调用ngOnInit()。可以通过以下方式实现:

import { Router } from '@angular/router';
constructor(private router: Router) {
    this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}

答案 2 :(得分:0)

更改参数通常不会导致ngOnInit。

如果您使用不同的参数导航到同一页面,则可以收听NavigationEnd等事件。基于此,您将能够触发您想要的功能。

import { Router, NavigationEnd } from '@angular/router';
export class AppComponent {
...
  constructor(public userService: UserService, router:Router) {
    router.events.forEach((event) => {
      if(event instanceof NavigationEnd) {
        console.log(location.pathname);
      }
      //NavigationStart
      // NavigationEnd
      // NavigationCancel
      // NavigationError
      // RoutesRecognized
    });

答案 3 :(得分:0)

我这样解决了这个问题。

假设您有一个带有news-list.component.ts的容器ngOnInit。它将当前queryParams保存在currentFilters中,如果没有,则进行简单的GET请求,否则进行POST请求。

ngOnInit() {
  this.route.queryParams.subscribe(queryParams => {
    if (!!queryParams) {
      this.currentFilters = <NewsFilter>{...queryParams, offset: 0, size: 6};
      this.news$ = this.newsPostsService.getNewsByFilter(this.currentFilters);
    } else {
      this.news$ = this.newsPostsService.getMainNews();
    }
  });
}

然后创建一个具有以下视图的组件<news-rubric></news-rubric>。您经过currentFilters,然后进入rubricClick,接下来将对其进行处理。

news-list.component.html

<ml-news-rubrics [currentFilters]="currentFilters"
                 (rubricClicked)="onRubricFilter($event)"
></ml-news-rubrics>

news-list.component.ts

onRubricFilter(filters: NewsFilter) {
  this.currentFilters = {...filters};
  this.router.navigate([], {queryParams: filters, relativeTo: this.route});
}

然后在news-rubric.component.ts内执行以下操作:

onRubricClicked(rubricId: string) {
  // check if filter exists and if not then put ID in filter
  if (!this.currentFilters.filterByAnyRubricIds) { 
    this.putIdInFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
  } else {
    // check if clicked ID is not in filter. put in filter
    if (!this.currentFilters.filterByAnyRubricIds.includes(rubricId)) { 
      this.putIdInFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
    } else { 
      // if ID in filter remove it from filter
      this.removeIdFromFilter('filterByAnyRubricIds', rubricId, this.currentFilters.filterByAnyRubricIds);
    }
  }
  this.rubricClicked.emit(this.currentFilters);
}

有最棘手的代码。它通过使用过滤后的ID更新其 key 来创建新的过滤器。

private putIdInFilter(key: string, value: any, list: any) {
  if (!list || !(list instanceof Array)) {
    if (!list) {
      this.currentFilters = {...this.currentFilters, [key]: [value]};
    } else {
      this.currentFilters = {...this.currentFilters, [key]: [this.currentFilters[key], value]};
    }
  } else {
    this.currentFilters = {...this.currentFilters, [key]: [...this.currentFilters[key], value]};
  }
}

private removeIdFromFilter(key: string, value: any, list: any) {
  if (!list || !(list instanceof Array)) {
    this.currentFilters = <NewsFilter>{
      ...this.currentFilters, [key]: null
    };
    return;
  }
  const filteredValues = [...list.filter(i => i !== value)];
  if (filteredValues.length > 0) {
    this.currentFilters = <NewsFilter>{
      ...this.currentFilters, [key]: filteredValues
    };
  } else {
    delete this.currentFilters[key];
  }
}

NewsFilter只是类似于QueryParams的接口,带有需要过滤的键。