【发布时间】:2017-08-14 13:15:18
【问题描述】:
我有一个带有多个过滤器的搜索表单。它们分布在文本输入、复选框 e 单选按钮中。与这些过滤器的每次交互都必须更新 URL 的查询字符串。
我也可以有以下情况:
http://example.com/search?myFilter=1&myFilter=2&myFilter=3
这将被翻译成这样的数组:myFilter = ['1', '2', '3']。
更新查询字符串的代码如下:
this.router.navigate([], {queryParams: myNewQueryString, relativeTo: this.routerActive});
其中“this.router”是 ActivatedRoute 的一个实例,“myNewQueryString”是包含查询字符串的新参数的对象。这段代码所做的是将路由重定向到自身更新查询字符串。
在使用新过滤器更新查询字符串之前,我需要确保不会丢失已经是 URL 一部分的其他过滤器。所以我需要做的是读取查询字符串,进行我需要的更改,然后将值返回到 URL。
要读取查询字符串,我使用以下代码:
const currentQueryString: any = this.routerActive.snapshot.queryParams;
我可以开始进行我需要的更改并继续前进,但问题是通过尝试更改此对象的属性,Angular 给了我以下错误:
TypeError:无法分配给对象的只读属性“参数”
发生此错误的原因是:
this.routerActive.snapshot.queryParams
都是只读的,所以我不能直接对它们进行修改。我需要做的是将属性复制到一个新对象,如下所示:
const newQueryString: any = {};
for (const key in currentQueryString) {
if (currentQueryString.hasOwnProperty(key)) {
newQueryString[key] = currentQueryString[key];
}
}
现在我有一个当前查询字符串的副本,我可以对其进行修改。问题是当我在一个数组中有多个值时,查询字符串不会得到更新。它只更新第一个值。
这是一个错误吗?有更好的方法吗?
我正在处理的完整代码是这样的:
//query is an object like: { 'param' : 'value' }
updateQueryString(query: any): void {
const currentQueryString: any = this.routerActive.snapshot.queryParams;
const newQueryString: any = {};
//Copy the current query string
for (const key in currentQueryString) {
if (currentQueryString.hasOwnProperty(key)) {
newQueryString[key] = currentQueryString[key];
}
}
// Apply the new filter to the copy of the query string
for (const key in query) {
if (query.hasOwnProperty(key)) {
if (newQueryString[key] instanceof Array) {
newQueryString[key].push(query[key]);
} else {
const filter = [];
filter.push(query[key]);
newQueryString[key] = filter;
}
}
}
this.router.navigate([], {queryParams: newQueryString, relativeTo: this.routerActive});
this.search(newQueryString);
}
我需要在此函数中进行其他验证,但现在我只想对 URL 进行更改。我将每个参数都视为一个数组,因为我可以有我在这个问题开头提到的那个场景。
【问题讨论】:
标签: javascript angular typescript query-string