【问题标题】:Angular 5 remove query paramAngular 5删除查询参数
【发布时间】:2018-07-11 04:51:12
【问题描述】:

如何从 URL 中删除查询参数?例如从www.expample.com/home?id=123&pos=sd&sd=iiiwww.expample.com/home?id=123&sd=iii

编辑: 这是我的版本:

this.activatedRoute.queryParams.subscribe(c => {
  const params = Object.assign({}, c);
  delete params.dapp;
  this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: params });
}).unsubscribe();

【问题讨论】:

    标签: javascript angular typescript


    【解决方案1】:

    您可以使用queryParamsHandlingmerge 选项删除查询参数,并为您希望删除的任何参数传入null

    // Remove query params
    this.router.navigate([], {
      queryParams: {
        'yourParamName': null,
        'youCanRemoveMultiple': null,
      },
      queryParamsHandling: 'merge'
    })
    

    此选项更简单,并且需要更少的工作来确保您不会删除其他参数。当你的组件被销毁时,你也不必担心清理 observable 订阅。

    【讨论】:

    • 任何想法如何从作为数组的查询参数中删除单个项目(例如,给定/path?p=a&p=b&p=c,如何仅删除p=c)?
    • 当您拥有来自应用程序其他部分的动态查询参数并且您只想删除非常特定的参数而不干扰其他地方可能添加的其他参数时,这种方式尤其适用.
    • 值得注意的是,这会触发导航事件。清除角度保护中的参数时遇到问题 - 导航已取消
    • 您可以使用选项skipLocationChange 来防止它触发导航事件。
    • 请注意router.navigate() 是异步的。因此,如果您尝试通过在同一任务(事件循环框架)中两次调用 router.navigate() 来删除两个查询参数 - 实际上只会从 url 中删除第二个参数。
    【解决方案2】:

    更新:@epelc 下面的答案是最新且正确的方法:https://stackoverflow.com/a/52193044/5932590


    不幸的是,目前没有明确的方法可以做到这一点:https://github.com/angular/angular/issues/18011。然而,正如 jasonaden 在链接线程上评论的那样,

    这可以通过合并新旧查询参数手动完成,删除您不想要的键。

    这是一种方法:

    假设您将 queryParams 存储在某些属性中。

    class MyComponent() {
      id: string;
      pos: string;
      sd: string;
    
      constructor(private route: ActivatedRoute, private router: Router) {}
    
      ngOnInit() {
        this.route.url.subscribe(next => {
          const paramMap = next.queryParamMap;
          this.id = paramMap.get('id');
          this.pos = paramMap.get('pos');
          this.sd = paramMap.get('sd');
        });
      }
    }
    

    清除pos 参数的方法如下所示:

    clearPosParam() {
      this.router.navigate(
        ['.'], 
        { relativeTo: this.route, queryParams: { id: this.id, sd: this.sd } }
      );
    }
    

    这将有效地导航到当前路由并清除您的 pos 查询参数,保持您的其他查询参数相同。

    【讨论】:

    • 谢谢你帮助我。
    • 很高兴为您提供帮助,请考虑通过单击复选标记“接受”答案,以便其他人知道您的问题已得到解答。欢迎来到 SO!
    • 这会泄露一个可观察的订阅。 Router 不会自动清理对route.url.subscribe 的订阅,必须在组件销毁时手动跟踪和处置。请考虑我下面的答案,它不需要任何订阅并且更简单。
    • 感谢@vince 的链接
    【解决方案3】:

    这是我找到的最好的解决方案,您可以更改 url 参数

    在构造函数中使用

        private _ActivatedRoute: ActivatedRoute
    

    然后在 init 或构造函数体中使用 this

        var snapshot = this._ActivatedRoute.snapshot;
        const params = { ...snapshot.queryParams };
        delete params.pos
        this.router.navigate([], { queryParams: params });
    

    【讨论】:

      【解决方案4】:

      我编写了一些 Router Prototype 覆盖,使处理查询参数变得更容易:

      想法是在路由器上调用一个方法,通过参数轻松管理路由,而不必每次都导出函数/重新声明功能。

      创建一个包含原型覆盖定义的index.d.ts 文件:

      // Ensure this is treated as a module.
      export { };
      
      declare module '@angular/router' {
          interface Router {
              updateQueryParams(activatedRoute: ActivatedRoute, params: Params): Promise<boolean>;
              setQueryParams(activatedRoute: ActivatedRoute, params: Params): Promise<boolean>;
              removeQueryParams(activatedRoute: ActivatedRoute, ...keys: string[]): Promise<boolean>;
          }
      }
      

      重要

      确保在使用此原型覆盖之前导入此文件,我刚刚将我的原型导入添加到app.module.ts

      import './shared/prototype-overrides/router.prototypes';


      设置查询参数

      这只会设置指定的查询参数,不会合并参数。

      场景

      您正在以下路线上:

      http://localhost:4200/#/some-route?param1=Test&amp;param2=test2

      并且您想SET将查询参数设置为param3=HelloWorld,并删除其他参数。

      用法

      this.router.setQueryParams(this.activatedRoute, { param3: 'HelloWorld' });
      
      // Will route to http://localhost:4200/#/some-route?param3=HelloWorld
      

      原型功能实现

      Router.prototype.setQueryParams = function (activatedRoute: ActivatedRoute, params: Params): Promise<boolean> {
          const context: Router = this;
      
          if (isNullOrUndefined(activatedRoute)) {
              throw new Error('Cannot update the query parameters - Activated Route not provided to use relative route');
          }
      
          return new Promise<boolean>((resolve) => {
              setTimeout(() => {
                  resolve(context.navigate([], {
                      relativeTo: activatedRoute,
                      queryParams: params
                  }));
              });
          });
      };
      

      更新查询参数

      这仅用于轻松更新 queryParams,它将合并路由中的查询参数,因此您没有重复的查询参数。

      场景

      您正在以下路线上:

      http://localhost:4200/#/some-route?param1=Test&amp;param2=test2

      并且您只想更新一个查询参数,param1param1=HelloWorld,而保留其他参数不变。

      用法

      this.router.updateQueryParams(this.activatedRoute, { param1: 'HelloWorld' });
      
      // Will route to http://localhost:4200/#/some-route?param1=HelloWorld&param2=test2
      

      原型功能实现

      Router.prototype.updateQueryParams = function (activatedRoute: ActivatedRoute, params: Params): Promise<boolean> {
          const context: Router = this;
      
          if (isNullOrUndefined(activatedRoute)) {
              throw new Error('Cannot update the query parameters - Activated Route not provided to use relative route');
          }
      
          // setTimeout required because there is an unintended behaviour when rapidly firing router updates in the same repaint cycle:
          // 
          // NavigationCancel - Navigation ID 2 is not equal to the current navigation id 3
          // https://stackoverflow.com/a/42802182/1335789
          return new Promise<boolean>((resolve) => {
              setTimeout(() => {
                  resolve(context.navigate([], {
                      relativeTo: activatedRoute,
                      queryParams: params,
                      queryParamsHandling: 'merge'
                  }));
              });
          });
      };
      

      删除查询参数

      场景

      您正在以下路线上:

      http://localhost:4200/#/some-route?param1=Test&amp;param2=test2&amp;param3=test3

      并且您只想删除一个(或多个,按字符串分隔的键)查询参数param1,而保留其他参数不变。

      用法

      this.router.removeQueryParams(this.activatedRoute, 'param1');
      
      // Will route to http://localhost:4200/#/some-route?param2=test2&param3=test3
      
      //Removing multiple parameters:
      this.router.removeQueryParams(this.activatedRoute, 'param1', 'param3');
      
      // Will route to http://localhost:4200/#/some-route?param2=test2
      

      原型功能实现

      Router.prototype.removeQueryParams = function (activatedRoute: ActivatedRoute, ...keys: string[]): Promise<boolean> {
          const context: Router = this;
      
          const currentParams: any = {};
          Object.keys(activatedRoute.snapshot.queryParams).forEach(key => {
              currentParams[key] = activatedRoute.snapshot.queryParams[key];
          });
          keys?.forEach(key => {
              delete currentParams[key];
          });
      
          return new Promise<boolean>((resolve) => {
              setTimeout(() =>
                  resolve(context.setQueryParams(activatedRoute, currentParams))
              );
          });
      };
      
      

      【讨论】:

        【解决方案5】:

        删除查询参数:

        import { Router, ActivatedRoute, Params } from '@angular/router';
        
        constructor(private router: Router, private activatedRoute: ActivatedRoute){
        }
        
        setQueryParams(){
            const qParams: Params = {};
            this.router.navigate([], {
                relativeTo: this.activatedRoute,
                queryParams: qParams,
                queryParamsHandling: ''
            });
        }
        

        【讨论】:

          【解决方案6】:

          您可以使用原生 javascript 操作从 url 中删除 queryParams 并使用 navigateByUrl 方法导航到 View

          https://angular.io/api/router/Router#navigateByUrl

          this.route.queryParams
                .subscribe((params: Params) => {
                  if (params && Object.keys(params).length > 0) {
                    const urlWithoutQueryParams = this.router.url.substring(0, this.router.url.indexOf('?'));
                    this.router.navigateByUrl(urlWithoutQueryParams)
                      .then(() => {
                      // any other functionality when navigation succeeds
                        params = null;
                      });
                  }
                });
             
          

          【讨论】:

            【解决方案7】:

            这对我有用:

            第 1 步:声明一个全局 url 搜索参数。

              incomingUrlParams: URLSearchParams;
            

            第 2 步:将查询保存在 urlsearchparam 全局变量中

            this.incomingUrlParams = new URLSearchParams(window.location.search);
            

            第 3 步:保存参数后在任何地方调用:

            clearQueryParamenters() {
                  let queryParamsJsonString: string = "";      
                  this.incomingUrlParams.forEach(function(value, key) {
                    queryParamsJsonString += '"' + key + '":' + null + ',';
                  });
                  queryParamsJsonString = "{" + queryParamsJsonString.trim().replace(/(^,)|(,$)/g, "") + "}";
                  this.router.navigate([], {
                    queryParams: JSON.parse(queryParamsJsonString),
                    queryParamsHandling: 'merge'
                  })
              }
            

            【讨论】:

              【解决方案8】:

              我正想这样做,但不使用路由器。这是我想出的:

              import { Location } from '@angular/common';
              import { HttpParams } from '@angular/common/http';
              
              declare location: Location; // get this from dependency injection
              
              const [path, query] = location.path().split('?');
              const params = new HttpParams({ fromString: query });
              const theValueIWant = params.get('theParamIWant');
              location.replaceState(path, params.delete('theParamIWant').toString());
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2019-05-10
                • 1970-01-01
                • 2016-02-29
                • 2019-03-29
                • 1970-01-01
                • 1970-01-01
                • 2018-11-14
                • 2018-07-08
                相关资源
                最近更新 更多