[英]navigateByUrl is failing to route the application
I have a button on a tab page to reset the app for a user by removing a storage entry:我在标签页上有一个按钮,用于通过删除存储条目为用户重置应用程序:
export class Tab1Page {
constructor(private router: Router, private storage: Storage, private toastController: ToastController) { }
async resetSettings() {
await this.storage.remove('welcomeComplete');
const toast = await this.toastController.create({
message: 'Your settings have been reset.',
duration: 2000
});
await toast.present();
console.log('before');
this.router.navigateByUrl('/');
console.log('after');
}
}
In the brower debugger, I can see that the entry is getting deleted from storage.在浏览器调试器中,我可以看到条目正在从存储中删除。 I am also presented with the toast.我也得到了祝酒词。
However, for some reason, the navigateByUrl method does not seem to be firing.但是,出于某种原因,navigateByUrl 方法似乎没有触发。 The above pages sits at the url '/tabs/tab1'.以上页面位于 url '/tabs/tab1'。 Both console.log() statements are executed and there isn't an error in the console.两个 console.log() 语句都已执行,并且控制台中没有错误。
I'm pretty new to front end development, so apologies if this is a basic newbie question.我是前端开发的新手,如果这是一个基本的新手问题,我深表歉意。
Update更新
my app-routing.module.ts我的 app-routing.module.ts
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { WelcomeGuard } from './welcome/welcome.guard';
const routes: Routes = [
{
path: '',
loadChildren: './tabs/tabs.module#TabsPageModule',
canActivate: [WelcomeGuard]
},
{
path: 'welcome',
loadChildren: './welcome/welcome.module#WelcomePageModule',
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, { enableTracing: true, preloadingStrategy: PreloadAllModules })
],
exports: [RouterModule]
})
export class AppRoutingModule {}
my welcome.guard.ts我的 welcome.guard.ts
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, CanActivate } from '@angular/router';
import { Observable } from 'rxjs';
import { Storage } from '@ionic/storage';
@Injectable({
providedIn: 'root'
})
export class WelcomeGuard implements CanActivate {
constructor(private router: Router, private storage: Storage) {}
async canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Promise<boolean> {
const welcomeComplete = await this.storage.get('welcomeComplete');
if (!welcomeComplete) {
this.router.navigateByUrl('/welcome');
}
return true;
}
}
I have changed my resetSettings() to the following:我已将我的 resetSettings() 更改为以下内容:
async resetSettings() {
await this.storage.remove('welcomeComplete');
const toast = await this.toastController.create({
message: 'Your settings have been reset.',
duration: 2000
});
toast.onDidDismiss().then(() => {
this.router.navigateByUrl('');
});
await toast.present();
}
Changing resetSettings() didn't fix the issue.更改 resetSettings() 没有解决问题。
It is problem with your guard, below change in welcome.guard.ts can help这是你的守卫有问题,下面的welcome.guard.ts更改可以帮助
if (!welcomeComplete) {
this.router.navigateByUrl('/welcome');
return false;
}
return true;
Reason:原因:
in resetSetting function after you call调用后在 resetSetting 函数中
toast.onDidDismiss().then(() => {
this.router.navigateByUrl('');
});
It tries to navigate to url : '' that matches first object in route array that is它尝试导航到与路由数组中的第一个对象匹配的 url : ''
...
{
path: '',
loadChildren: './tabs/tabs.module#TabsPageModule',
canActivate: [WelcomeGuard]
}
....
then it executes guard function and then you are returning true in any case, it means page got approaval to navigate to '/' and as you are in /tabs/tab1 which is child path of current route setting, so it does nothing and stays in same page.然后它执行保护功能,然后你在任何情况下都返回true ,这意味着页面获得了导航到“/”的批准,就像你在 /tabs/tab1 这是当前路由设置的子路径一样,所以它什么都不做并停留在同一页面。
router.navigatByUrl
returns a promise with a boolean, which indicates whether routing was successful. router.navigatByUrl
返回一个带有布尔值的promise,表示路由是否成功。 I would recommend to log, whether your routing is successful like this:我建议记录,您的路由是否成功,如下所示:
this.router.navigateByUrl('/').then(success => console.log(`routing status: ${success}`));
I'm guessing that the result will be false, because of your guard.我猜结果会是假的,因为你的警卫。 So if I am right, disable your WelcomeGuard by removing it from your route or returning true.因此,如果我是对的,请通过从您的路线中删除它或返回 true 来禁用您的 WelcomeGuard。
I guess the problem happens because of routing inside of the guard again, but returning true two lines later.我想问题是由于再次在警卫内部路由而发生的,但在两行之后返回 true 。
Like the others, I would check the route you are trying to navigate to matches your router path configuration:像其他人一样,我会检查您尝试导航的路线以匹配您的路由器路径配置:
this.router.navigateByUrl('/');
const routes: Routes = [
{
path: '/', component: YourComponent, pathMatch: 'full', data: {
...
}
},
My default route is usually ' ', as opposed to ' / '.我的默认路由通常是 ' ',而不是 ' / '。
They cover using router.navigate / router.navigateByUrl pretty well here: How to use router.navigateByUrl and router.navigate in Angular他们在这里很好地涵盖了使用 router.navigate / router.navigateByUrl: How to use router.navigateByUrl and router.navigate in Angular
If you include the rest of your relevant code, we might be able to help more with your specific issue.如果您包含其余的相关代码,我们或许能够为您的具体问题提供更多帮助。
I hope this helps you 👍希望对你有帮助👍
Make sure your services methods return an observable.确保您的服务方法返回一个 observable。
import { Observable } from 'rxjs';
remove() {
const obs = Observable.create(observer => {
observer.next('Hello');
// Throw an error.
if (error) {
observer.error("my error");
}
});
return obs;
}
import { Observable } from 'rxjs';
create() {
const obs = Observable.create(observer => {
observer.next('Hello');
// Throw an error.
if (error) {
observer.error("my error");
}
});
return obs;
}
import { zip } from 'rxjs';
export class Tab1Page {
constructor(
private router: Router,
private storage: Storage,
private toastController: ToastController
) {
// this.resetSettings();
}
resetSettings() {
const a = this.storage.remove('welcomeComplete');
const b = this.toastController.create({
message: 'Your settings have been reset.',
duration: 2000
});
zip(a, b).subscribe( res => {
this.router.navigateByUrl('/');
// or
this.router.navigate(['/']);
});
}
}
Should you will try with navigate instead of navigateByUrl您是否应该尝试使用导航而不是navigateByUrl
this.router.navigate(['/']);
Or或者
this.router.navigate(['']);
Also you could你也可以
toast.onDidDismiss().then(()=> {
this.router.navigate(['/']);
});
Depending your router.取决于你的路由器。
In my case, it was happening because there was a redirection preceding the path resolution.在我的例子中,它的发生是因为在路径解析之前有一个重定向。
When accessing /
, I was redirecting the user to /login
so the login page could be loaded.访问/
时,我将用户重定向到/login
以便可以加载登录页面。
However, the path-matching strategy I was using was 'prefix' which means the Angular router would choose the redirection instruction for any route prefixed with /
, ie, all routes .但是,我使用的路径匹配策略是“prefix”,这意味着 Angular 路由器将为任何前缀为/
的路由选择重定向指令,即所有路由。
Changing the path-matching strategy to 'full' instructed the Angular route to redirect to /login
only when the full path is /
.将路径匹配策略更改为“完整”指示 Angular 路由仅在完整路径为/
时重定向到/login
。 So, the /
gets redirected to /login
and the /forgot-password
do not get redirected to /login
anymore.因此, /
被重定向到/login
,而/forgot-password
不再被重定向到/login
。
{
path: '',
redirectTo: 'login',
pathMatch: 'prefix' // <---- this should be 'full'
},
{
path: 'login',
loadChildren: () => import('./login').then(m => m.LoginPageModule),
},
{
path: 'forgot-password',
loadChildren: () => import('./forgot-password').then(m => m.ForgotPasswordPageModule)
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.