我正在努力在我的Angular 14和Ionic 6应用程序中创建一个功能。我希望在我的应用程序中创建一个"欢迎"屏幕,该屏幕只在用户第一次打开应用程序时出现,然后再也不会出现。
我不知道如何保存用户屏幕已经被用户看到的状态,应用程序不应该在第二次打开应用程序时加载它…
我的想法是做一个存储服务来保存状态,然后有一个路由保护来处理重定向和页面显示…
我现在收到这个错误,不知道如何修复它…我是否正确地将值存储在存储服务中,还是我的代码完全错误?错误:
错误:src/app/保安/first-load.guard。ts:17:50 -错误TS2339:属性'then'在类型'void'上不存在。[ng] [ng] 17
this.storageService.getValue('first_time').then((value) =>{(ng)
我的代码如下:
storage.service.ts:
export class StorageService {
constructor(
private storage: Storage
) {
this.init();
}
async init() {
await this.storage.create();
}
setValue(key: 'first_time', value: 'done') {
this.storage.set(key, value);
}
getValue(key: 'first_time') {
this.storage.get(key).then((value) => {
console.log(value);
});
}
}
和这里的first-load.guard。我正在调用这个服务:
export class FirstLoadGuard implements CanActivate {
constructor(
private storageService: StorageService,
private router: Router
) {}
canActivate(route: ActivatedRouteSnapshot): Promise<boolean>
{
return new Promise(resolve => {
this.storageService.getValue('first_time').then((value) => {
if (value !== null) {
this.router.navigateByUrl('/login');
resolve(false);
}
else {
this.storageService.setValue('first_time', 'done');
resolve(true);
}
});
});
}
}
如果我需要提供更多的代码,请随时给我留下评论:)我希望有人能帮助我
你的函数定义有问题。:
用于声明格式,您将变量定义为常量,这可能就是您获得null的原因。
改变为key: string
和value: string
服务的storage
中的key: 'first_time'
和value: 'done'
。或者如果你想为你的函数输入设置一个默认值:
getValue(key: string = 'first_time')
或者如果你的输入真的是常量而不是输入,你最好在你的服务中定义它们,而不是接受输入:
key= 'first_time';
value= 'done';
setValue() {
this.storage.set(this.key, this.value);
}
getValue() {
this.storage.get(this.key).then((value) => {
console.log(value);
});
}
得到错误消息的原因
错误:src/app/保安/first-load.guard。ts:17:50 -错误TS2339:属性'then'不存在类型'void'。[ng] [ngthis.storageService.getValue (first_time)((值)=比;{(ng)
是因为您的storageService.getValue()
实际上没有返回任何东西。要修复此错误,您需要返回带有存储中的值的承诺:
getValue(key: 'first_time') {
return this.storage.get(key).then((value) => {
console.log(value);
return value;
});
}
如果你可以去掉console.log()
,它可以更短:
getValue(key: 'first_time') {
return this.storage.get(key);
}
在你的代码中添加一些注释:
正如@AmirAli Saghaei在另一个答案中所写的,你目前正在将函数参数的类型声明为静态值,即调用setValue()
与任何其他参数值作为first_time
和done
会在编译时给你一个类型错误。这很可能不是你想要的。
如果您想为参数提供默认值,请使用=
而不是:
:
setValue(key = 'first_time', value = 'done') {
// ...
}
如果你想指定期望的类型,你应该使用string
:
setValue(key: string, value: string) {
// ...
}
由于init()
仅由构造函数同步调用,因此此处使用async
/await
没有区别。你必须在构造函数中await
它,构造函数必须返回一个承诺——这是一个不好的做法。
在路由保护中,您不需要创建new Promise()
,但您可以链接并返回getValue
的承诺:
canActivate(route: ActivatedRouteSnapshot): Promise<boolean>
{
return this.storageService.getValue('first_time').then((value) => {
if (value !== null) {
this.router.navigateByUrl('/login');
return false;
}
else {
this.storageService.setValue('first_time', 'done');
return true;
}
});
}
或者使用async
/await
:
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean>
{
const value = await this.storageService.getValue('first_time');
if (value !== null) {
this.router.navigateByUrl('/login');
return false;
}
else {
this.storageService.setValue('first_time', 'done');
return true;
}
}
所以你的代码的一个更简化的版本可以是:
export class StorageService {
constructor(
private storage: Storage
) {
this.storage.create();
}
setValue(key: string, value: string) {
this.storage.set(key, value);
}
getValue(key: string) {
return this.storage.get(key);
}
}
export class FirstLoadGuard implements CanActivate {
constructor(
private storageService: StorageService,
private router: Router
) {}
async canActivate(route: ActivatedRouteSnapshot): Promise<boolean>
{
const value = await this.storageService.getValue('first_time');
if (value !== null) {
this.router.navigateByUrl('/login');
return false;
}
else {
this.storageService.setValue('first_time', 'done');
return true;
}
}
}