查询参数更改时,路由未更新
Posted
技术标签:
【中文标题】查询参数更改时,路由未更新【英文标题】:On query parameters change, route is not updating 【发布时间】:2018-04-08 18:05:14 【问题描述】:在我的应用程序中,有多个链接,其中我有一些links
具有相同的route
但具有不同的query parameters
。
说,我有这样的链接:
.../deposits-withdrawals
.../deposits-withdrawals?id=1
.../deposits-withdrawals?id=2&num=12321344
当我在上述路线之一并且从上面提到的另一条路线本地时,路线不会改变。甚至没有像ngOnInit
或ngOnChanges
这样的任何函数被调用。我已将参数从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>
【问题讨论】:
【参考方案1】:我曾经遇到过这个问题。你能放一些代码,或者你尝试过的解决方案吗? 我会给你一些对我有用的东西,但你最好给我一些更多的细节,以便我能提供帮助。 假设我们在这里: some_url/deposits-withdrawals 我们希望导航,只更改参数。
let url = "id=2&num=12321344"
this.router.navigate(['../', url], relativeTo: this.route );
希望对你有帮助:/
====================================编辑==== ===============================
您必须检测到查询参数已更改。为此,您可以在组件的构造函数中为 queryParameters 更改添加一个侦听器。这可以使用你的 router 来完成:
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>
【讨论】:
我已经更新了这个问题。请让我知道您还想知道什么。我也会提供的。 好的,你会试试这个吗? ***.com/a/41678403/3428620 ?告诉它是否适合你。它应该工作 从上面的评论中,你的意思是没有办法使用查询参数来做到这一点?constructor(route:ActivatedRoute) route.params.subscribe(val => // put the code from
ngOnInit` 这里 ); ` 表示如果查询参数发生变化,您将向路由添加侦听器。这意味着您必须先导航(使用查询参数,在 html 或 ts 中。例如 。然后,你在路由监听器中检测到这些变化。跨度>
@AsmaG 谢谢。你是我找到的第一个简单的解决方案。我想知道这么简单的行为如何需要更改提供程序,而我只需要订阅路由。【参考方案2】:
更改参数通常不会导致 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】:更新查询参数时必须重新调用ngOnInit()
。这可以通过以下方式实现:
import Router from '@angular/router';
constructor(private router: Router)
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
【讨论】:
【参考方案4】:我这样解决了这个问题。
假设您有一个容器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
的接口,带有需要过滤的键。
【讨论】:
以上是关于查询参数更改时,路由未更新的主要内容,如果未能解决你的问题,请参考以下文章