Angular2 查询参数订阅触发两次 [英] Angular2 Query Params Subscription Fires Twice

查看:85
本文介绍了Angular2 查询参数订阅触发两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试处理 OAuth 登录场景,如果用户登陆查询字符串中带有 authorization_code 的页面,我们会处理令牌并继续如果他们登陆如果页面没有那个,我们会检查本地存储中是否存在现有令牌,确保它仍然有效,并根据其有效性重定向到登录或继续.

Trying to handle an OAuth login scenario where if the user lands on a page with authorization_code in the query string, we process the token and continue or if they land on the page without that, we check local storage for their existing token, make sure it's still valid and either redirect to login or continue, based on its validity.

问题在于,在我们检查 authorization_code 查询字符串参数是否存在的地方,订阅被触发两次.第一次它是空的,第二次它在字典中有正确的值.

The problem is that where we're checking for the existence of the authorization_code query string param, the subscription is firing twice. The first time it is empty, the second time it has the correct value in the dictionary.

app.component.ts

export class App implements OnInit {
    constructor(private _router: ActivatedRoute) {
    }

    public ngOnInit(): void {
        console.log('INIT');
        this._route.queryParams.subscribe(params => {
            console.log(params);
        });
    }
}

此代码输出:

Plunker(您需要将其弹出到新窗口并添加查询字符串 ?test=test).

Plunker (you'll need to pop it out into a new window and add a query string ?test=test).

问题

  1. 是不是我做错了什么让它触发了两次?
  2. 我不能只是忽略带有条件的空对象,因为在这种情况下我们需要验证现有的身份验证令牌——是否有另一种方法来解决这个问题,而不是完全破解?

推荐答案

Router observables (as another answer提到) BehaviorSubject 主题,它们不同于常规的 RxJS Subject 或Angular 2 EventEmitter 因为它们将初始值推送到序列(在 queryParams 的情况下为空对象).

Router observables (as another answer mentions) are BehaviorSubject subjects, they differ from regular RxJS Subject or Angular 2 EventEmitter in that they have the initial value pushed to the sequence (an empty object in the case of queryParams).

一般来说,订阅初始化逻辑的可能性是可取的.

Generally the possibility of subscribing with initialization logic is desirable.

可以用skip操作符跳过初始值.

The initial value can be skipped with skip operator.

this._route.queryParams
.skip(1)
.subscribe(params => ...);

但更自然的处理方法是过滤掉所有不相关的参数(初始 params 属于这一类).还可以使用 distinctUntilChanged 运算符过滤重复的 authorization_code 值,以避免对后端进行不必要的调用.

But more natural way to handle this is to filter out all irrelevant params (initial params falls into this category). Duplicate authorization_code values can also be filtered with distinctUntilChanged operator to avoid unnecessary calls to the backend.

this._route.queryParams
.filter(params => 'authorization_code' in params)
.map(params => params.authorization_code)
.distinctUntilChanged()
.subscribe(authCode => ...);

请注意,Angular 2 导入了有限数量的 RxJS 操作符(至少在 @angular/router 的情况下是 map).如果未使用完整的 rxjs/Rx 包,则可能需要导入正在使用的额外运算符(filterdistinctUntilChanged)import 'rxjs/add/operator/'.

Notice that Angular 2 imports a limited amount of RxJS operators (at least map in the case of @angular/router). If full rxjs/Rx bundle isn't used, it may be necessary to import extra operators (filter, distinctUntilChanged) that are in use with import 'rxjs/add/operator/<operator_name>'.

这篇关于Angular2 查询参数订阅触发两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆