Ionic 6基于服务获取的数据导航到组件的最佳方式



我有一个Ionic应用程序,它可以登录并将用户数据存储在电容器存储中。

this.httpService.login(this.username, this.password).subscribe(async (user: any) => {
await Preferences.set({ key: 'user', value: JSON.stringify(user)});
this.router.navigate(['']);
});

在我的主页中,我想检查我是否登录(电容器存储器的用户密钥中是否有任何内容(。如果没有,它应该直接进入登录页面,如果有,它会保持原样。我不知道这是否是最好的方法(也许有更好的方法在Angular路由中加载组件?(。我现在正在做的是:

我有一个用户服务:

import { Injectable } from '@angular/core';
import { User } from '../models/user';
import { Preferences } from '@capacitor/preferences';
@Injectable({providedIn: 'root'})
export class UserService {
private user: User = new User();
private userSet = false;
constructor() {
Preferences.get({ key: 'user' }).then((data: any) => {
if(data) {
const userObj = JSON.parse(data.value);
this.user = Object.assign(this.user, userObj);
// console.log(this.user);
this.userSet = true;
}
});
}
hasUser() {
return this.userSet;
}
}

我的主页上有这项服务,我会检查它以进行适当的导航:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { HttpService } from '../services/httpService';
import { UserService } from '../services/userService';
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss']
})
export class HomePage implements OnInit {
constructor(private httpService: HttpService, private userService: UserService, private router: Router) {}
ngOnInit() {
console.log(this.userService.hasUser());
if(!this.userService.hasUser()) { console.log('navigating'); this.router.navigate(['/login']);}
}
}

由于电容器首选项的异步特性,这并不像您想象的那样有效。当它试图检查用户时,它还没有找到它。那么,有什么更好、正确的方法可以做到这一点呢?

为了避免时间问题,您可以让服务返回PromiseObservable,以便在收到异步值时通知消费者。

然后,您可以实现Route Guard(CanActivate(,以便在未设置用户时重定向到登录页面。当使用路由保护时,不需要在组件中放置重定向逻辑,只需将保护添加到路由定义中即可。

  1. 在服务中返回承诺:
export class UserService {
private user: Promise<User|undefined> = Preferences.get({ key: 'user' }).then(
data => data ? JSON.parse(data.value) : undefined
);
hasUser(): Promise<boolean> {
return this.user.then(user => !!user);
}
}
  1. 实施路线保护:
export class AuthGuard implements CanActivate {
constructor(userService: UserService, private router: Router) { }
async canActivate() {
return await this.userService.hasUser()
? true
: router.parseUrl('/login');
}
}
  1. 保护必要的路线:
const routes: Routes = [
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
];

最新更新