javascript - Angular 4 : can't update the query string of URL

标签 javascript angular typescript query-string

我有一个带有多个过滤器的搜索表单。它们分布在文本输入、复选框和单选按钮中。与这些过滤器的每次交互都必须更新 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: Cannot assign to read only property 'parameter' of object

发生此错误是因为以下属性:

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

最佳答案

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

为了提供这个新实例,我们可以改变:

这个:

newQueryString[key] = currentQueryString[key];

进入这个:

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

通过创建数组的新实例,问题得到解决,我需要的更改现在反射(reflect)在 URL 上。

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

如果有人遇到这样的问题,显然只需使用对象的新实例就可以了。

关于javascript - Angular 4 : can't update the query string of URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45675398/

相关文章:

angular - 带有 Azure AD (MSAL) 的 Cypress

angular - 空注入(inject)器错误 : No provider for InjectionToken DocumentToken

angular - 使用Charles-Proxy错误状态重写是-1而不是503

visual-studio - 在哪里可以找到安装在 Visual Studio 中的 TypeScript 版本?

class - 为什么 Typescript 类会自动实现接口(interface)?

typescript - 在第 3 方库中重新声明不正确的 typescript 类型

javascript - 如何使用 Greasemonkey 修改带有 id 的 div 中的标签

javascript - 在 express 中通过表格发布数据以进行 Sequelize

javascript - 如何从不同的模块调用 React Native 类中的函数

javascript - 部分 View 中不显眼的客户端验证不起作用