【问题标题】:get only final value from angular queryParams从角度查询参数中仅获取最终值
【发布时间】:2019-12-12 08:26:14
【问题描述】:

我的目标是找出查询参数project 是否在加载应用程序时设置。同时我还必须加载项目列表。当我得到这两个信息时,我可以继续我的逻辑。

这是我目前得到的结果

combineLatest([
  this.route.queryParams.pipe(pluck('project')),
  this.projects$.pipe(first(),filter(p => p && p.length > 0))
]).subscribe(([projectParam, projects]) => {
  console.log(projectParam, projects);
});

this.route是ActivatedRoute类型:https://angular.io/api/router/ActivatedRoute

projects$ observable 非常理想。但是 queryParams observable 被调用了两次。一次使用值undefined,然后使用实际值。但我只想要最后一个值。 由于 url 是可选的,因此两个选项都有效。

知道如何让 queryParams 在最终值上触发。

【问题讨论】:

    标签: angular rxjs angular-routing


    【解决方案1】:

    尝试使用最后一个 rxjs 运算符

    this.route.queryParams.pipe(last(), pluck('project'))
    

    【讨论】:

    • 这不起作用。 subscribe 中的代码永远不会被调用。我把它放到 ngOnInit 中:this.route.queryParams .pipe(last(), pluck('project')) .subscribe((project) => console.log(project));
    【解决方案2】:

    this.route.queryParams 在内部实现为一个从不完成的主题,但您希望它在第一个不同于 undefined 的值之后立即完成。

    所以你可以使用 takeWhile 和可选的第二个参数:

    this.route.queryParams.pipe(
      takeWhile(val => val === undefined, true), // or maybe !Boolean(val)
      takeLast(1),
      pluck('project')),
    )
    

    或者只使用filter() amd take(1) 会更容易。

    【讨论】:

    • 是的,如果我希望 project 成为必需的值,类似的东西可以工作,但如果查询参数中没有 project,那么这将永远不会完成
    • 那你想做什么?等到queryParams 发出一个未定义的值或取第一个值是什么?
    • 如果url中有project参数,那么我要它的值,否则ùndefined`
    【解决方案3】:

    您可以使用跳过运算符跳过第一个。

     combineLatest([
          this.route.queryParams.pipe(pluck('project')),
          this.projects$.pipe(first(),filter(p => p && p.length > 0))
        ]).pipe(skip(1)).subscribe(([projectParam, projects]) => {
          console.log(projectParam, projects);
        });
    

    【讨论】:

      【解决方案4】:

      为什么你不能简单地订阅 route.queryParams 并检查它是否有 project 参数。

      这是我完成任务的想法。

      ngOnInit() {
          this.route.queryParams.subscribe(queryParams => {
              if (queryParams.project) {
                  // proceed with your logic
              }
          });
      }
      

      【讨论】:

        【解决方案5】:

        感谢这里的讨论:https://github.com/angular/angular/issues/12157 我想出了以下解决方案:

        private get finalQueryParams$(): Observable<Params> {
          return merge(
            // get urls with query params like /test?project=test
            this.route.queryParams.pipe(
              filter(params => Object.keys(params).length > 0)
            ),
            // get urls without query params like /test
            this.route.queryParams.pipe(
              filter(() => !(window.location.href || '').includes('?')),
              map(() => ({}))
            )
          );
        }
        

        它只触发一次,我得到了 queryParams 的真实值。

        在上面的代码中,我只需将其更改为

        combineLatest([
          this.finalQueryParams$.pipe(pluck('project')),
          this.projects$.pipe(first(),filter(p => p && p.length > 0))
        ]).subscribe(([projectParam, projects]) => {
          console.log(projectParam, projects);
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-10-27
          • 1970-01-01
          • 2018-10-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-24
          • 1970-01-01
          相关资源
          最近更新 更多