首页 文章

Angular 2 Routing问题,路由到空白页面

提问于
浏览
1

我遇到了新的Angular 2路由器的问题 . 我有一个按钮单击事件,它调用一个函数从登录组件路由到仪表板页面 . 两者都是主app组件的子组件 . 当我单击按钮并且函数触发时,我使用navigateByUrl()函数从登录导航到仪表板页面 . 但是当调用该函数时,浏览器URL显示localhost:52370 / dashboard?和浏览器中的黑页 . 我不确定这个问题源自何处 . 这是我的app.routes.ts文件

const appRoutes: Routes = [
{ path: "", component: HomeComponent },
{ path: "home", redirectTo: "" },
{ path: "login", component: LoginComponent },
{ path: "dashboard", component: DashboardComponent },
];

export const AppRoutingProviders: any[] = [];
export const AppRouting: ModuleWithProviders = RouterModule.forRoot(appRoutes);

login.component.ts文件

constructor(private router: Router, private route: ActivatedRoute) { }

public login() {
    this.loginStatus = true;
    this.onLogin.emit(this.loginStatus);
    this.router.navigateByUrl("dashboard")
        .then(function () {
            console.log("success");
        }).catch(function (err) {
            console.log(err);
        });
}

3 回答

  • 0

    所以我在navigateByUrl()调用上得到了类似的问题 . 我发现的其中一件事是它们似乎与时间相关的问题,因为我在重定向之间徘徊 . 我目前的设置包括以下路线:

    • / - RedirectComponent

    • /仪表板 - 为管理员加载

    • / projects - 为非管理员加载

    • / login - 登录页面,重定向到/

    在登录并随后重定向到/或直接命中/后,RedirectComponent检查已验证状态并确定用户是否是管理员 . 然后调用navigateByUrl()以将用户发送到正确的路由 . 请注意,第一个导航到/尚未完全完成,这可以从我连接的全局路由器事件监听器中看到:

    _router.events.subscribe((event:Event) => {
      if (event instanceof NavigationEnd) {
        // When the route is '/', location.path actually returns ''.
        let newRoute = this._location.path() || '/';
        // If the route has changed
        if (this.currentRoute !== newRoute) {
          console.log('App(): new route', this.currentRoute, newRoute);
          this.currentRoute = newRoute;
        }
      }
    });
    

    在执行navigateByUrl('/')时,会按预期加载我的RedirectComponent,然后调用navigateByUrl('/ dashboard') . 这会导致页面加载完全空白,并且/ dashboard导航路径事件永远不会触发 . 我认为可能有一些逻辑阻止导航直到上一个导航完成?我的路由器事件监听器在停止路由之前打印以下内容并出现空白屏幕:

    App(): new route "/login" "/" (2)
    

    正如你在(2)中看到的那样,似乎在Safari中所有路由都以某种方式发生了两次,而在Chrome中它只发生一次 . 甚至可能是某些阻止/仪表板路由被触发的逻辑可能已经“修复”以处理Safari等浏览器的一些潜在问题,其中事件/组件发射两次并且您不希望实际发生多个导航 . . ?但纯粹的猜测 .

    可能有更好的方法来解决潜在的问题,但我找到了一个简单但虽然不优雅的解决方案,我们所有的Angular老手都会在我们的工具柜中出现时间问题 . 我们好老的frenemy setTimeout(...,0):

    setTimeout(() => {
            this.router.navigateByUrl('/dashboard');
          }, 0);
    

    /仪表板路线然后正确激活,导航按照预期在/导航完成后进行 . 可能有一个更好的机制或使用ChangeDetectorRef之类的替代猴子补丁,但这使我现在的工作做得很好 . 装运它 .

    可能值得一试只是为了统治内外 . 希望这可以帮助 . 如果您找到了不同的解决方案,那么对于遇到类似问

  • 0

    在导航到新路线之前,您可以等待路由器“稳定” .

    import { debounceTime, take } from 'rxjs/operators';
    
    
    public login() {
        this.loginStatus = true;
        this.onLogin.emit(this.loginStatus);
    
        //wait for router events to settle (i.e. no router events in last 50 ms)
        return this.router.events.pipe(
            debounceTime(50),
            take(1)
        ).toPromise().then(()=>{
            //now that the router has settled, navigate to your new route
            return this.router.navigateByUrl("dashboard")   
        });
    }
    
  • 2

    我遇到了类似的问题,我忘了在 app.component.html 页面添加router-outlet,它作为占位符标记模板中的位置,路由器应显示该插座的组件 . 因此,请检查是否添加了 <router-outlet></router-outlet> 标记 .

    为了安全起见,这里是你需要构建的基本格式,以便使用angular 6路由和导航在模块级别(例如:app.module.ts)定义路由并在导入中添加它们:[]使用RouterModule.forRoot()在相同的模块级别,在html文件中添加<router-outlet> </ router-outlet>标记(例如:app.component.html),它可以作为要加载的组件的占位符 . 相同的模块级别将Router添加到组件文件的构造函数中(例如:app.component.ts)在同一个组件文件中(在第3点中提到)使用this.router.navigate(['/ home'])或者这个.router.navigateByUrl('/ home')导航到新组件,记得从“@ angular / router”导入{RouterModule,Routes};在所有上述打字稿文件中 . 有关详细信息,请参阅angular文档 .

相关问题