查询参数更改时,路由不更新

On query parameters change, route is not updating

在我的应用程序中,有多个链接,其中我有一些 links 具有相同的 route 但具有不同的 query parameters.

比如说,我有这样的链接:

.../deposits-withdrawals
.../deposits-withdrawals?id=1
.../deposits-withdrawals?id=2&num=12321344

当我在上面的其中一条路线中并且从上面提到的另一条路线出发时,路线没有改变。甚至 ngOnInitngOnChanges 成为 called.I 的任何函数都没有将参数从 queryParameters 更改为 matrixParameters 但没有成功。我浏览了许多链接和答案。但是,其中 none 解决了我的问题。帮我解决这个问题。

谢谢...

编辑:

<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>

我曾经遇到过这个问题。你能放一些代码,或者你试过的解决方案吗? 我会给你一些对我有用的东西,但你最好给我更多的细节,这样我就可以提供帮助。 假设我们在这里: some_url/deposits-withdrawals 我们希望导航,仅更改参数。

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

希望对您有所帮助:/

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

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

    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>

更改参数通常不会导致 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
        });

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

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

这个问题我是这样解决的

假设您有一个 news-list.component.tsngOnInit 的容器。它将当前 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这样的界面,需要过滤键。