Angular Ionic 4-如何使用防护装置在一条路线上实施canActivate
在我的ionic应用程序中,我有两条路线,欢迎页面和主页,在欢迎页面中,用户必须回答一个问题,然后,他被重定向到主页,我试图做的是,如果用户已经回答了问题,跳过第一条路线 这是我的警卫:Angular Ionic 4-如何使用防护装置在一条路线上实施canActivate,angular,ionic-framework,Angular,Ionic Framework,在我的ionic应用程序中,我有两条路线,欢迎页面和主页,在欢迎页面中,用户必须回答一个问题,然后,他被重定向到主页,我试图做的是,如果用户已经回答了问题,跳过第一条路线 这是我的警卫: export class CheckWelcomeGuard implements CanActivate { constructor(private router: Router, private dbstorage: DatabaseService) {} canActivate( route:
export class CheckWelcomeGuard implements CanActivate {
constructor(private router: Router, private dbstorage: DatabaseService) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
this.dbstorage.getDatabaseState().subscribe(ready => {
if (ready) {
this.dbstorage.checkSettingsValue("WELCOME_PAGE_PASSED").then(data => {
if (data) {
return true;
}
});
}
});
this.router.navigate(["/welcome"], {
queryParams: { redirect: state.url },
replaceUrl: true
});
return false;
}
}
取决于此,重定向发生在检查执行之前!继续重定向到欢迎页面
private database: SQLiteObject;
private dbReady: BehaviorSubject<boolean> = new BehaviorSubject(false);
settings = new BehaviorSubject([]);
constructor(
private platform: Platform,
private sqlite: SQLite,
private http: HttpClient
) {
this.platform.ready().then(() => {
this.createDatabaseObject();
});
}
createDatabaseObject() {
this.sqlite
.create({
name: "testapp.db",
location: "default"
})
.then((db: SQLiteObject) => {
this.database = db;
this.seedDatabase();
});
}
seedDatabase() {
this.http
.get("assets/testapp.sql", { responseType: "text" })
.subscribe(sql => {
this.database.executeSql(sql, [])
.then(() => {
// this.clearSettings();
console.log('Executed SQL');
this.dbReady.next(true);
})
.catch(e => console.log(e));
});
}
// Database state
// ready: true
// not ready: false
getDatabaseState() {
return this.dbReady.asObservable();
}
私有数据库:SQLiteObject;
private-dbReady:BehaviorSubject=new-BehaviorSubject(false);
设置=新行为主体([]);
建造师(
私有平台:平台,
私有sqlite:sqlite,
私有http:HttpClient
) {
this.platform.ready()。然后(()=>{
这个.createDatabaseObject();
});
}
createDatabaseObject(){
这个是sqlite
.创造({
名称:“testapp.db”,
位置:“默认”
})
.然后((db:SQLiteObject)=>{
this.database=db;
这个.seedDatabase();
});
}
种子数据库(){
这是http
.get(“assets/testapp.sql”,{responseType:“text”})
.subscribe(sql=>{
this.database.executeSql(sql,[])
.然后(()=>{
//这是clearSettings();
log('Executed SQL');
this.dbReady.next(true);
})
.catch(e=>console.log(e));
});
}
//数据库状态
//准备好了吗
//未准备好:错误
getDatabaseState(){
返回此.dbReady.asObservable();
}
问题在于,对this.dbstorage.getDatabaseState().subscribe…
的调用是一个异步操作,因此是非阻塞的。这意味着浏览器将进行呼叫,但不会等待应答,而是将继续正常执行您的代码,在本例中是this.router.navigate([“/welcome”],…
。因此this.router.navigate([“/welcome”],…
将始终被调用,而不管此.dbstorage.getDatabaseState().subscribe的结果如何。您需要让代码等待数据库响应。我喜欢这样做:
导出类CheckWelcomeGuard实现CanActivate{
构造函数(专用路由器:路由器,专用数据库存储:数据库服务){}
异步canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot){
const ready=wait this.dbstorage.getDatabaseState().toPromise();
如果(准备就绪){
const data=wait this.dbstorage.checksettings值(“欢迎页面通过”);
如果(数据){
返回true;
}否则{
this.router.navigate([“/welcome”]{
查询参数:{redirect:state.url},
replaceUrl:true
});
返回false;
}
}否则{
this.router.navigate([“/welcome”]{
查询参数:{redirect:state.url},
replaceUrl:true
});
返回false;
}
}
}
问题是,您对this.dbstorage.getDatabaseState().subscribe…
的调用是一个异步操作,因此它是非阻塞的。这意味着浏览器将进行调用,但不会等待应答,而是将继续正常执行您的代码,在本例中是this.router.navigate([“/welcome”],…
。正因为如此,this.router.navigate([“/welcome”]),…
将始终被调用,而不管this.dbstorage.getDatabaseState().subscribe的结果如何。订阅…
。您需要让代码等待数据库响应。我喜欢这样做:
导出类CheckWelcomeGuard实现CanActivate{
构造函数(专用路由器:路由器,专用数据库存储:数据库服务){}
异步canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot){
const ready=wait this.dbstorage.getDatabaseState().toPromise();
如果(准备就绪){
const data=wait this.dbstorage.checksettings值(“欢迎页面通过”);
如果(数据){
返回true;
}否则{
this.router.navigate([“/welcome”]{
查询参数:{redirect:state.url},
replaceUrl:true
});
返回false;
}
}否则{
this.router.navigate([“/welcome”]{
查询参数:{redirect:state.url},
replaceUrl:true
});
返回false;
}
}
}
我不确定这是一条路,但这里有一条路可以走
我假设getDatabaseState()
和checksetingsvalue()
都返回一个可观察值。Angular将自动订阅
canActivate
方法返回的可观测值
export class CheckWelcomeGuard implements CanActivate {
constructor(
private router: Router,
private dbstorage: DatabaseService
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.dbstorage.getDatabaseState()
.pipe(
switchMap(ready => !ready
? this.redirectToWelcome(state)
: this.dbstorage.checkSettingsValue('WELCOME_PAGE_PASSED')
.pipe(
switchMap(data => !data
? this.redirectToWelcome(state)
: of(true)
)
)
)
);
}
redirectToWelcome(state: RouterStateSnapshot): Promise<boolean> {
return this.router.navigate(['/welcome'], {
queryParams: { redirect: state.url },
replaceUrl: true
});
}
}
导出类CheckWelcomeGuard实现CanActivate{
建造师(
专用路由器:路由器,
专用数据库存储:数据库服务
) {}
激活(
路由:ActivatedRouteSnapshot,
状态:RouterStateSnapshot
):可观察的|承诺|布尔| UrlTree{
返回此.dbstorage.getDatabaseState()
.烟斗(
开关映射(就绪=>!就绪
?此.重定向TowerCome(状态)
:this.dbstorage.checkSettingsValue('WELCOME\u PAGE\u PASSED')
.烟斗(
开关映射(数据=>!数据
?此.重定向TowerCome(状态)
:of(真)
)
)
)
);
}
重定向TowelCome(状态:RouterStateSnapshot):承诺{
返回此.router.navigate(['/welcome']{
查询参数:{redirect:state.url},
replaceUrl:true
});
}
}
我不确定这是一条路,但这里有一条路可以走
我假设getDatabaseState()
和checksetingsvalue()
都返回一个可观察值。Angular将自动订阅
canActivate
方法返回的可观测值
export class CheckWelcomeGuard implements CanActivate {
constructor(
private router: Router,
private dbstorage: DatabaseService
) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.dbstorage.getDatabaseState()
.pipe(
switchMap(ready => !ready
? this.redirectToWelcome(state)
: this.dbstorage.checkSettingsValue('WELCOME_PAGE_PASSED')
.pipe(
switchMap(data => !data
? this.redirectToWelcome(state)
: of(true)
)
)
)
);
}
redirectToWelcome(state: RouterStateSnapshot): Promise<boolean> {
return this.router.navigate(['/welcome'], {
queryParams: { redirect: state.url },
replaceUrl: true
});
}
}
导出类CheckWelc