【问题标题】:Angular2 DataStore - authGuards no longer not working when using rxjs SubjectAngular2 DataStore - 使用 rxjs 主题时 authGuards 不再工作
【发布时间】:2023-03-21 07:12:02
【问题描述】:

我正在构建一个用户配置文件数据存储,因此我的 Angular 2 应用程序不需要如此频繁地访问服务器。当我直接使用该服务时,该应用程序当前运行良好,但是当我在其中添加我的数据存储层时,它的行为就好像我的 observable 只发出一次(当我的导航栏组件读取它们的 currentuser.name 时)。使用该服务的组件似乎可以工作,而我的 AuthGuards 不再工作(它使用 UserProfileStore 来获取用户信息)。我怀疑我错误地使用了主题和/或需要使用 BehaviourSubjectReplaySubject 的一些变体,但我真的不知道从哪里开始。我的代码是半基于这个例子的:Cory Ryan Angular 2 Observable Data Services

关于我缺少什么的任何想法?

user-profile.store.ts

@Injectable()
export class UserProfileStore implements OnDestroy {
private _currentUser:SjfrUser;
private _currentUser$: Subject<MyAppUser>;
private _subscription: Subscription;

constructor(private authService: AuthService) {
    this._currentUser$ = <Subject<MyAppUser>> new Subject();
}

getCurrentUser = () : Observable<MyAppUser> => {

    if (!this._currentUser) {
        let currentUser$ = this.authService.getCurrentUser(); // Performs http
        this._subscription = currentUser$.subscribe((currentUser: MyAppUser) => {                
            this._currentUser = currentUser;
            this._currentUser$.next(this._currentUser);
        });
    }

    return this._currentUser$.asObservable();
}

ngOnDestroy() {
    this._subscription.unsubscribe();
}

}

Auth-Guard.service.ts

@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
    constructor(private userProfileStore: UserProfileStore, private authService: AuthService, private router: Router) { }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {        

        let url: string = state.url;

        //var currentUser$ = this.authService.getCurrentUser(); // Works with this
        var currentUser$ = this.userProfileStore.getCurrentUser(); // No longer works            

        return currentUser$.map(x => {
            console.log("AuthGuard" + x.userName);  // This code no longer gets executed when using the datastore
            if (x.isExternalUser && url === '/external') {
                return true;
            } else if (x.isInternalUser && url === '/internal') {
                return true;
            } else {
                this.router.navigate(['/pagenotfound']);
                return false;
            }
        });     


    }
...

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    尝试在 map 之后使用 .first() 进行操作

    @Injectable()
    export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
        constructor(private userProfileStore: UserProfileStore, private authService: AuthService, private router: Router) { }
    
        canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {        
    
            let url: string = state.url;
    
            //var currentUser$ = this.authService.getCurrentUser(); // Works with this
            var currentUser$ = this.userProfileStore.getCurrentUser(); // No longer works            
    
            return currentUser$.map(x => {
                console.log("AuthGuard" + x.userName);  // This code no longer gets executed when using the datastore
                if (x.isExternalUser && url === '/external') {
                    return true;
                } else if (x.isInternalUser && url === '/internal') {
                    return true;
                } else {
                    this.router.navigate(['/pagenotfound']);
                    return false;
                }
            }).first();     
    
    
        }

    【讨论】:

    • 那行不通。我也在尝试创建一些外观,以便消费者(观察者)不必改变他们使用数据存储的方式。我只是希望它表现得像一个普通的 observable 而不会冲击服务器。
    猜你喜欢
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-27
    • 2016-12-22
    相关资源
    最近更新 更多