【问题标题】:navigateByUrl is failing to route the applicationnavigateByUrl 无法路由应用程序
【发布时间】:2019-08-11 02:13:53
【问题描述】:

我在标签页上有一个按钮,可以通过删除存储条目为用户重置应用:

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() 语句都执行了,控制台没有错误。

我是前端开发的新手,如果这是一个基本的新手问题,请道歉。


更新

我的 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 {}

我的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() 并没有解决问题。

【问题讨论】:

  • 您可以尝试将this.router.navigateByUrl('/'); 包装在setTimeout() 中吗?像这样:setTimeout(() =&gt; { this.router.navigateByUrl('/'); }, 0);
  • 谢谢,但这也没用。
  • 我认为问题存在于您的代码示例之外。也许与路由器配置有关。 navigateByUrl 返回一个promise,成功时解析为true,失败时解析为false。你知道这个承诺是否正在解决吗?如果它没有解决,那么您可能希望让路由器变得健谈,这样您就可以看到正在发生的事情。这可以在应用路由器中通过将enableTracing 设置为true - angular.io/api/router/RouterModule#forroot 来完成
  • 相关页面是否有 canActivated / canDeactivate 守卫?
  • 你能创建一个显示问题的堆栈闪电战吗?

标签: angular ionic4


【解决方案1】:

这是你的后卫有问题,下面更改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 中,这是当前的路线设置,所以它什么也不做,并且停留在同一页面上。

【讨论】:

【解决方案2】:

router.navigatByUrl 返回一个带有布尔值的 Promise,表示路由是否成功。我建议记录一下您的路由是否成功:

this.router.navigateByUrl('/').then(success => console.log(`routing status: ${success}`));

我猜结果会是假的,因为你的警惕。因此,如果我是对的,请通过将其从您的路线中删除或返回 true 来禁用您的 WelcomeGuard。

我猜这个问题的发生是因为再次在守卫内部路由,但在两行之后返回 true。

【讨论】:

    【解决方案3】:

    像其他人一样,我会检查您尝试导航到的路由是否与您的路由器路径配置匹配:

    this.router.navigateByUrl('/');
    
    const routes: Routes = [
        {
            path: '/', component: YourComponent, pathMatch: 'full', data: {
            ...
            }
        },
    

    我的默认路由通常是'',而不是'/'。

    他们在这里很好地使用了 router.navigate / router.navigateByUrl: How to use router.navigateByUrl and router.navigate in Angular

    如果您包含其余的相关代码,我们可能会针对您的具体问题提供更多帮助。

    【讨论】:

      【解决方案4】:

      希望对你有帮助?

      确保你的服务方法返回一个 observable。

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

      【讨论】:

        【解决方案5】:

        您是否应该尝试使用 navigation 而不是 navigateByUrl

        this.router.navigate(['/']);
        

        或者

        this.router.navigate(['']);
        

        你也可以

        toast.onDidDismiss().then(()=> {
          this.router.navigate(['/']);
        });
        

        取决于您的路由器。

        【讨论】:

        • 当两个console.log都在on navigation周围触发时,问题与toast无关
        猜你喜欢
        • 1970-01-01
        • 2016-10-25
        • 2021-07-13
        • 2021-05-23
        • 2019-06-27
        • 2020-02-08
        • 2021-11-19
        • 2020-10-14
        • 2019-04-16
        相关资源
        最近更新 更多