首页 文章

Angular 4:无法更新URL的查询字符串

提问于
浏览
1

我有一个带有几个过滤器的搜索表单 . 它们分布在文本输入,复选框和无线电按钮中 . 与这些过滤器的每次交互都必须更新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];
    }
}

现在我有一个当前查询字符串的副本,我可以对其进行修改 . 问题是,当我在Array中有多个值时,查询字符串不会更新 . 它仅更新第一个值 .

这是一个错误吗?有更好的方法吗?

我正在处理的完整代码是:

//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进行更改 . 我将每个参数都视为一个数组,因为我可以在这个问题的开头提到我所提到的那个场景 .

1 回答

  • 1

    似乎问题是在从当前查询字符串复制到新查询字符串的过程中 . 出于某种原因,我们需要提供数组的新实例,以便Angular可以理解更改并将其应用于URL .

    要提供这个新实例,我们可以更改:

    这个:

    newQueryString[key] = currentQueryString[key];
    

    进入:

    newQueryString[key] = Array.from(currentQueryString[key]);
    

    通过创建数组的新实例,问题得以解决,我所需的更改现在反映在URL上 .

    还有其他一些验证需要使这个读取 - 复制 - 更改 - 应用查询字符串进程正常,但我不认为这些细节是非常相关的一旦问题是如何处理ActivatedRoute提供的实例 .

    如果有人偶然发现了这样的问题,显然只是处理对象的新实例,你就可以了 .

相关问题