Angular 7导航强行归根

Angular 7 navigation forcibly returning to root

自从我从 Angular 5 升级到 Angular 7 后,我遇到了路由问题。我用谷歌搜索了很多,但都无济于事。

本质上,问题在于从一页导航到另一页。如果在导航栏上,我 select 'Plans'(如在付款计划中),它会将我带到付款计划列表(来自 Stripe 的列表)。然后,一旦我 select 一个计划,我就使用 router.navigate 转到 Stripe 付款表单页面(模板驱动表单)。当我调试时,我可以看到它暂时导航到付款表单页面,但随后又返回到 /.

我的路线:

const appRoutes = [
{ path: 'home', component: HomeComponent },
{ path: 'accounts/login', component: LoginFormComponent },
{ path: 'accounts/register', component: RegistrationFormComponent },
{ path: 'plans', component: StripePlansComponent },
//{ path: 'pay', component: StripeFormComponent, canActivate: [IsLoggedinGuardService, HasSelectedPlanGuardService] },
{ path: 'pay', component: StripeFormComponent },
{ path: 'privacy', component: PrivacyStatementComponent },
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }

];

我目前已将我的 Pay 路线注释掉,以确保不会怪罪于 Gaurds。

我的导航菜单组件:

<li class="nav-link" routerLinkActive="active">
    <a [routerLink]="['plans']">
        <span class='fa fa-money-bill-alt' style="margin-right: 10px"></span> Pay </a>
</li>

我的计划组成部分:

import { Component, Inject, OnInit, OnDestroy, ElementRef, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { PaymentService } from '../../shared/services/payment.service';

@Component({
    templateUrl: 'stripe-plans.component.html',
    styleUrls: ['stripe-plans.component.css'],
})

export class StripePlansComponent implements OnInit {

    public plans: Observable<StripePlan[]>;
    selectedPlan: StripePlan | undefined = undefined;

constructor(private _paymentService: PaymentService, private _router: Router) {

}

    ngOnInit() {
        this.plans = this.GetAllPlans();
    }

    GetAllPlans()  {
        return this._paymentService.getAvailablePlans();
    };

    ClickHandler(plan: StripePlan) {
        this._paymentService.setSelectedPlan(plan);
        this._router.navigate(['pay']);
    }
}

我的计划HTML(我正在使用异步管道来处理subscribing/unsubscribing):

<div class="center">
<h1>Payment Plans</h1>

<div class="row">
    <div class="col-sm-2" *ngFor="let plan of plans | async">
        <div class="card" style="width: 18rem;">
            <div class="card-header">
                <div class="price-container">
                    <div class="price">
                        <span class="label">Buy</span>
                        <span class="number">{{ plan.Amount / 100 | currency: plan.Currency:'symbol-narrow':'1.2-2' }}</span>
                        <span class="label">Now</span>
                    </div>
                </div>
            </div>
            <div class="card-body">
                <h3 class="card-title">{{ plan.PlanId }}</h3>
                <p class="card-text">{{ plan.Amount / 100 | currency: plan.Currency:'symbol-narrow':'1.2-2' }} per {{ plan.Interval }} </p>
                <a href="#" class="btn btn-primary" (click)="ClickHandler(plan)">Select</a>
            </div>
        </div> 
    </div>
</div>    

正如您在上面的 javascript 中看到的,我是从点击处理程序中导航的。

我的表单组件:

import { Component, NgZone, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { UserService } from '../../shared/services/user.service';
import { PaymentService } from '../../shared/services/payment.service';
import { NgxSpinnerService } from 'ngx-spinner';
import * as moment from 'moment';

@Component({
    templateUrl: 'stripe-form.component.html',
    styleUrls: ['stripe-form.component.css']
})

export class StripeFormComponent implements OnInit {

    Stripe: any;
    model: any = {};

   message: string | undefined = undefined;
   errorMessage: string | undefined = undefined;

   selectedPlan: StripePlan | undefined;
   submitted: boolean = false;
   valuesMonth: any[];
   valuesYear: any[];

  constructor(private paymentService: PaymentService, private _zone: NgZone, private _router: Router, private _userService: UserService, private spinner: NgxSpinnerService) {
      this.Stripe = ( < any > window).Stripe;
  }

  ngOnInit() {
       this.selectedPlan = this.paymentService.getSelectedPlan();
  }

路由器输出:

> VM41 vendor.js:66038 Router Event: NavigationStart
> VM41 vendor.js:66033 NavigationStart(id: 2, url: '/plans')
VM41 vendor.js:66033 NavigationStart {id: 2, url: "/plans", navigationTrigger: "imperative", restoredState: null}
VM41 vendor.js:66038 Router Event: RoutesRecognized
VM41 vendor.js:66033 RoutesRecognized(id: 2, url: '/plans', urlAfterRedirects: '/plans', state: Route(url:'', path:'') { Route(url:'plans', path:'plans') } )
VM41 vendor.js:66033 RoutesRecognized {id: 2, url: "/plans", urlAfterRedirects: "/plans", state: RouterStateSnapshot}
VM41 vendor.js:66038 Router Event: GuardsCheckStart
VM41 vendor.js:66033 GuardsCheckStart(id: 2, url: '/plans', urlAfterRedirects: '/plans', state: Route(url:'', path:'') { Route(url:'plans', path:'plans') } )
VM41 vendor.js:66033 GuardsCheckStart {id: 2, url: "/plans", urlAfterRedirects: "/plans", state: RouterStateSnapshot}
VM41 vendor.js:66038 Router Event: ChildActivationStart
VM41 vendor.js:66033 ChildActivationStart(path: '')
VM41 vendor.js:66033 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
VM41 vendor.js:66038 Router Event: ActivationStart
VM41 vendor.js:66033 ActivationStart(path: 'plans')
VM41 vendor.js:66033 ActivationStart {snapshot: ActivatedRouteSnapshot}
VM41 vendor.js:66038 Router Event: GuardsCheckEnd
VM41 vendor.js:66033 GuardsCheckEnd(id: 2, url: '/plans', urlAfterRedirects: '/plans', state: Route(url:'', path:'') { Route(url:'plans', path:'plans') } , shouldActivate: true)
VM41 vendor.js:66033 GuardsCheckEnd {id: 2, url: "/plans", urlAfterRedirects: "/plans", state: RouterStateSnapshot, shouldActivate: true}
VM41 vendor.js:66038 Router Event: ResolveStart
VM41 vendor.js:66033 ResolveStart(id: 2, url: '/plans', urlAfterRedirects: '/plans', state: Route(url:'', path:'') { Route(url:'plans', path:'plans') } )
VM41 vendor.js:66033 ResolveStart {id: 2, url: "/plans", urlAfterRedirects: "/plans", state: RouterStateSnapshot}
VM41 vendor.js:66038 Router Event: ResolveEnd
VM41 vendor.js:66033 ResolveEnd(id: 2, url: '/plans', urlAfterRedirects: '/plans', state: Route(url:'', path:'') { Route(url:'plans', path:'plans') } )
VM41 vendor.js:66033 ResolveEnd {id: 2, url: "/plans", urlAfterRedirects: "/plans", state: RouterStateSnapshot}
VM41 vendor.js:66038 Router Event: ActivationEnd
VM41 vendor.js:66033 ActivationEnd(path: 'plans')
VM41 vendor.js:66033 ActivationEnd {snapshot: ActivatedRouteSnapshot}
VM41 vendor.js:66038 Router Event: ChildActivationEnd
VM41 vendor.js:66033 ChildActivationEnd(path: '')
VM41 vendor.js:66033 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
VM41 vendor.js:66038 Router Event: NavigationEnd
VM41 vendor.js:66033 NavigationEnd(id: 2, url: '/plans', urlAfterRedirects: '/plans')
vendor.js:66033 NavigationEnd {id: 2, url: "/plans", urlAfterRedirects: "/plans"}
vendor.js:66038 Router Event: Scroll
vendor.js:66033 Scroll(anchor: 'null', position: 'null')
vendor.js:66033 Scroll {routerEvent: NavigationEnd, position: null, anchor: null}
vendor.js:66038 Router Event: NavigationStart
vendor.js:66033 NavigationStart(id: 3, url: '/pay')
vendor.js:66033 NavigationStart {id: 3, url: "/pay", navigationTrigger: "imperative", restoredState: null}
vendor.js:66038 Router Event: RoutesRecognized
vendor.js:66033 RoutesRecognized(id: 3, url: '/pay', urlAfterRedirects: '/pay', state: Route(url:'', path:'') { Route(url:'pay', path:'pay') } )
vendor.js:66033 RoutesRecognized {id: 3, url: "/pay", urlAfterRedirects: "/pay", state: RouterStateSnapshot}
vendor.js:66038 Router Event: GuardsCheckStart
vendor.js:66033 GuardsCheckStart(id: 3, url: '/pay', urlAfterRedirects: '/pay', state: Route(url:'', path:'') { Route(url:'pay', path:'pay') } )
vendor.js:66033 GuardsCheckStart {id: 3, url: "/pay", urlAfterRedirects: "/pay", state: RouterStateSnapshot}
vendor.js:66038 Router Event: ChildActivationStart
vendor.js:66033 ChildActivationStart(path: '')
vendor.js:66033 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
vendor.js:66038 Router Event: ActivationStart
vendor.js:66033 ActivationStart(path: 'pay')
vendor.js:66033 ActivationStart {snapshot: ActivatedRouteSnapshot}
vendor.js:66038 Router Event: GuardsCheckEnd
vendor.js:66033 GuardsCheckEnd(id: 3, url: '/pay', urlAfterRedirects: '/pay', state: Route(url:'', path:'') { Route(url:'pay', path:'pay') } , shouldActivate: true)
vendor.js:66033 GuardsCheckEnd {id: 3, url: "/pay", urlAfterRedirects: "/pay", state: RouterStateSnapshot, shouldActivate: true}
vendor.js:66038 Router Event: ResolveStart
vendor.js:66033 ResolveStart(id: 3, url: '/pay', urlAfterRedirects: '/pay', state: Route(url:'', path:'') { Route(url:'pay', path:'pay') } )
vendor.js:66033 ResolveStart {id: 3, url: "/pay", urlAfterRedirects: "/pay", state: RouterStateSnapshot}
vendor.js:66038 Router Event: ResolveEnd
vendor.js:66033 ResolveEnd(id: 3, url: '/pay', urlAfterRedirects: '/pay', state: Route(url:'', path:'') { Route(url:'pay', path:'pay') } )
vendor.js:66033 ResolveEnd {id: 3, url: "/pay", urlAfterRedirects: "/pay", state: RouterStateSnapshot}
vendor.js:66038 Router Event: ActivationEnd
vendor.js:66033 ActivationEnd(path: 'pay')
vendor.js:66033 ActivationEnd {snapshot: ActivatedRouteSnapshot}
vendor.js:66038 Router Event: ChildActivationEnd
vendor.js:66033 ChildActivationEnd(path: '')
vendor.js:66033 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
vendor.js:66038 Router Event: NavigationEnd
vendor.js:66033 NavigationEnd(id: 3, url: '/pay', urlAfterRedirects: '/pay')
vendor.js:66033 NavigationEnd {id: 3, url: "/pay", urlAfterRedirects: "/pay"}
vendor.js:66038 Router Event: Scroll
vendor.js:66033 Scroll(anchor: 'null', position: 'null')
vendor.js:66033 Scroll {routerEvent: NavigationEnd, position: null, anchor: null}
Navigated to https://localhost:5001/
platform-browser.js:216 Router Event: NavigationStart
platform-browser.js:211 NavigationStart(id: 1, url: '/')
platform-browser.js:211 NavigationStart {id: 1, url: "/", navigationTrigger: "imperative", restoredState: null}
core.js:15702 Angular is running in the development mode. Call enableProdMode() to enable the production mode.
platform-browser.js:216 Router Event: RoutesRecognized
platform-browser.js:211 RoutesRecognized(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
platform-browser.js:211 RoutesRecognized {id: 1, url: "/", urlAfterRedirects: "/home", state: RouterStateSnapshot}
platform-browser.js:216 Router Event: GuardsCheckStart
platform-browser.js:211 GuardsCheckStart(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
platform-browser.js:211 GuardsCheckStart {id: 1, url: "/", urlAfterRedirects: "/home", state: RouterStateSnapshot}
platform-browser.js:216 Router Event: ChildActivationStart
platform-browser.js:211 ChildActivationStart(path: '')
platform-browser.js:211 ChildActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:216 Router Event: ActivationStart
platform-browser.js:211 ActivationStart(path: 'home')
platform-browser.js:211 ActivationStart {snapshot: ActivatedRouteSnapshot}
platform-browser.js:216 Router Event: GuardsCheckEnd
platform-browser.js:211 GuardsCheckEnd(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } , shouldActivate: true)
platform-browser.js:211 GuardsCheckEnd {id: 1, url: "/", urlAfterRedirects: "/home", state: RouterStateSnapshot, shouldActivate: true}
platform-browser.js:216 Router Event: ResolveStart
platform-browser.js:211 ResolveStart(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
platform-browser.js:211 ResolveStart {id: 1, url: "/", urlAfterRedirects: "/home", state: RouterStateSnapshot}
platform-browser.js:216 Router Event: ResolveEnd
platform-browser.js:211 ResolveEnd(id: 1, url: '/', urlAfterRedirects: '/home', state: Route(url:'', path:'') { Route(url:'home', path:'home') } )
platform-browser.js:211 ResolveEnd {id: 1, url: "/", urlAfterRedirects: "/home", state: RouterStateSnapshot}
platform-browser.js:216 Router Event: ActivationEnd
platform-browser.js:211 ActivationEnd(path: 'home')
platform-browser.js:211 ActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:216 Router Event: ChildActivationEnd
platform-browser.js:211 ChildActivationEnd(path: '')
platform-browser.js:211 ChildActivationEnd {snapshot: ActivatedRouteSnapshot}
platform-browser.js:216 Router Event: NavigationEnd
platform-browser.js:211 NavigationEnd(id: 1, url: '/', urlAfterRedirects: '/home')
platform-browser.js:211 NavigationEnd {id: 1, url: "/", urlAfterRedirects: "/home"}
platform-browser.js:216 Router Event: Scroll
platform-browser.js:211 Scroll(anchor: 'null', position: 'null')
platform-browser.js:211 Scroll {routerEvent: NavigationEnd, position: null, anchor: null}

此外,除了 "Navigated to https://localhost:5001/".

之外,路由输出中没有任何异常显示

如果有任何帮助,我将不胜感激。这真的让我很困惑。

您是否尝试从 link 中删除 href 属性:<a href="#" class="btn btn-primary" (click)="ClickHandler(plan)">Select</a> 有时它会影响路由器的行为。