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

93ze6v8z  于 2022-12-08  发布在  Ionic
关注(0)|答案(1)|浏览(162)

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

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']);}
  }

}

由于电容器首选项的异步特性,这并不像你想象的那样工作。当它试图检查用户时,它仍然没有完成对它的查找。那么,有什么更好和正确的方法来完成这项工作呢?

uidvcgyl

uidvcgyl1#

为了避免计时问题,可以让服务返回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] },
];

相关问题