navigateByUrl 无法路由应用程序
navigateByUrl is failing to route the application
我在标签页上有一个按钮,用于通过删除存储条目为用户重置应用程序:
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');
}
}
在浏览器调试器中,我可以看到条目正在从存储中删除。我也得到了祝酒词。
但是,由于某种原因,navigateByUrl 方法似乎没有触发。
以上页面位于 url '/tabs/tab1'。两个 console.log() 语句都已执行,并且控制台中没有错误。
我是前端开发的新手,如果这是一个基本的新手问题,我深表歉意。
更新
我的应用-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 {}
我的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;
}
}
我已将我的 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();
}
更改 resetSettings() 未能解决问题。
您是否应该尝试使用 navigate 而不是 navigateByUrl
this.router.navigate(['/']);
或者
this.router.navigate(['']);
你也可以
toast.onDidDismiss().then(()=> {
this.router.navigate(['/']);
});
取决于您的路由器。
与其他人一样,我会检查您尝试导航的路线以匹配您的路由器路径配置:
this.router.navigateByUrl('/');
const routes: Routes = [
{
path: '/', component: YourComponent, pathMatch: 'full', data: {
...
}
},
我的默认路由通常是“ ”,而不是“ / ”。
他们在这里很好地介绍了如何使用 router.navigate / router.navigateByUrl:
如果您包含其余的相关代码,我们或许能够为您解决特定问题提供更多帮助。
希望对你有帮助
确保您的服务方法 return 是可观察的。
storage.service.ts
import { Observable } from 'rxjs';
remove() {
const obs = Observable.create(observer => {
observer.next('Hello');
// Throw an error.
if (error) {
observer.error("my error");
}
});
return obs;
}
toastController.service.ts
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(['/']);
});
}
}
router.navigatByUrl
returns 带有布尔值的promise,表示路由是否成功。我会建议记录,你的路由是否成功是这样的:
this.router.navigateByUrl('/').then(success => console.log(`routing status: ${success}`));
我猜结果会是假的,因为你的警惕。因此,如果我是对的,请将 WelcomeGuard 从您的路线中删除或返回 true 以禁用它。
我猜问题的发生是因为再次在守卫内部路由,但两行后返回 true。
你的守卫有问题,下面welcome.guard.ts的变化可以帮助
if (!welcomeComplete) {
this.router.navigateByUrl('/welcome');
return false;
}
return true;
原因:
调用后在 resetSetting 函数中
toast.onDidDismiss().then(() => {
this.router.navigateByUrl('');
});
它尝试导航到 url : '' 匹配路由数组中的第一个对象
...
{
path: '',
loadChildren: './tabs/tabs.module#TabsPageModule',
canActivate: [WelcomeGuard]
}
....
然后它执行保护功能,然后你返回 true 在任何情况下,这意味着页面已获准导航到“/”,正如你在 /tabs/tab1 这是当前路由设置的子路径,所以它什么也不做,停留在同一页面。
在我的例子中,这是因为在路径解析之前有一个重定向。
访问 /
时,我将用户重定向到 /login
,以便可以加载登录页面。
然而,我使用的 path-matching 策略是 'prefix',这意味着 Angular 路由器将为任何前缀为 /
的路由选择重定向指令,即, 所有路线.
将 path-matching 策略更改为 'full' 指示 Angular 路由仅在完整路径为 /
时重定向到 /login
。
因此,/
被重定向到 /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)
},
我在标签页上有一个按钮,用于通过删除存储条目为用户重置应用程序:
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');
}
}
在浏览器调试器中,我可以看到条目正在从存储中删除。我也得到了祝酒词。
但是,由于某种原因,navigateByUrl 方法似乎没有触发。 以上页面位于 url '/tabs/tab1'。两个 console.log() 语句都已执行,并且控制台中没有错误。
我是前端开发的新手,如果这是一个基本的新手问题,我深表歉意。
更新
我的应用-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 {}
我的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;
}
}
我已将我的 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();
}
更改 resetSettings() 未能解决问题。
您是否应该尝试使用 navigate 而不是 navigateByUrl
this.router.navigate(['/']);
或者
this.router.navigate(['']);
你也可以
toast.onDidDismiss().then(()=> {
this.router.navigate(['/']);
});
取决于您的路由器。
与其他人一样,我会检查您尝试导航的路线以匹配您的路由器路径配置:
this.router.navigateByUrl('/');
const routes: Routes = [
{
path: '/', component: YourComponent, pathMatch: 'full', data: {
...
}
},
我的默认路由通常是“ ”,而不是“ / ”。
他们在这里很好地介绍了如何使用 router.navigate / router.navigateByUrl:
如果您包含其余的相关代码,我们或许能够为您解决特定问题提供更多帮助。
希望对你有帮助
确保您的服务方法 return 是可观察的。
storage.service.ts
import { Observable } from 'rxjs';
remove() {
const obs = Observable.create(observer => {
observer.next('Hello');
// Throw an error.
if (error) {
observer.error("my error");
}
});
return obs;
}
toastController.service.ts
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(['/']);
});
}
}
router.navigatByUrl
returns 带有布尔值的promise,表示路由是否成功。我会建议记录,你的路由是否成功是这样的:
this.router.navigateByUrl('/').then(success => console.log(`routing status: ${success}`));
我猜结果会是假的,因为你的警惕。因此,如果我是对的,请将 WelcomeGuard 从您的路线中删除或返回 true 以禁用它。
我猜问题的发生是因为再次在守卫内部路由,但两行后返回 true。
你的守卫有问题,下面welcome.guard.ts的变化可以帮助
if (!welcomeComplete) {
this.router.navigateByUrl('/welcome');
return false;
}
return true;
原因:
调用后在 resetSetting 函数中
toast.onDidDismiss().then(() => {
this.router.navigateByUrl('');
});
它尝试导航到 url : '' 匹配路由数组中的第一个对象
...
{
path: '',
loadChildren: './tabs/tabs.module#TabsPageModule',
canActivate: [WelcomeGuard]
}
....
然后它执行保护功能,然后你返回 true 在任何情况下,这意味着页面已获准导航到“/”,正如你在 /tabs/tab1 这是当前路由设置的子路径,所以它什么也不做,停留在同一页面。
在我的例子中,这是因为在路径解析之前有一个重定向。
访问 /
时,我将用户重定向到 /login
,以便可以加载登录页面。
然而,我使用的 path-matching 策略是 'prefix',这意味着 Angular 路由器将为任何前缀为 /
的路由选择重定向指令,即, 所有路线.
将 path-matching 策略更改为 'full' 指示 Angular 路由仅在完整路径为 /
时重定向到 /login
。
因此,/
被重定向到 /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)
},