首页 文章

Angular 4路由奇怪的行为:除非页面刷新,否则不呈现子模块

提问于
浏览
2

我一直在寻找解决这种奇怪行为的方法,但没有运气 .

  • angular 4控制台或javascript控制台中没有错误

  • 使用Angular CLI(Angular 4)

我对角度路由器的行为非常奇怪 . 我正在尝试从父AppModule加载子路由,它有自己的模块 . 路线在/ products

在/ products模块(products.module.ts):我有3条路线:

  • /产品/概述

  • / products / intro [重定向到/ products]

  • / products / product /:product

产品模块应该拥有自己的导航栏,位于全局AppModule的导航栏上,导航栏位于products.component.html组件模板中的router-outlet上方 .

The main problem: 当我将页面(不使用角度routerLink)加载到/ products时:

  • 两个导航栏都可见

  • LOADED页面(ex / intro)导航栏可见,但子组件(IntroComponent)是 NOT visible

  • 但是,当我导航到/ products模块路径中的任何其他子路径时(例如/概述或/ product /:product):它渲染得很好 . 因此,无论在整页上加载什么路由都不可见 .

The weirdest part: 当我在非产品(ex / home)的路线上加载页面(刷新),然后使用主导航栏导航到/ products:

  • 导航栏是 not visible ?????

  • 子组件(ex / intro组件)是可见的

在过去的几天里,这给我带来了很大的痛苦 .

现在,一些代码:

app.module.ts [main AppModule]

@NgModule({
    declarations: [
        AppComponent,
        HomeComponent,
        LoginComponent,
        SignupComponent,
        NotFoundComponent,
        LogoutComponent,
        ErrorComponent,
        AboutComponent,
        ApiComponent,
        StatusComponent,
        SupportComponent,
        CustomersComponent,
        JobsComponent,
        TosComponent
    ],
    imports: [
        BrowserModule,
        HttpModule,
        FormsModule,
        SharedModule,
        //ProductsModule,
        AppRoutingModule
    ],
    providers: [
        UserService,
        AuthGuard,
        ErrorService,
        NavbarService,
        MailerService,
        IOService,
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

shared.module.ts - 这有我的ViewAppComponent(它只是一个带有全局导航栏的路由器插座)和其他全局组件(如应在所有路径上显示的导航栏和页脚)

@NgModule({
  imports: [
    CommonModule,
      RouterModule
  ],
  declarations: [ViewAppComponent, FooterComponent, NavbarComponent],
  exports: [CommonModule, ViewAppComponent, FooterComponent, NavbarComponent]
})
export class SharedModule { }

app-routing.module.ts

const routes: Routes = [
    {
        path: '',
        component: ViewAppComponent,
        children: [
            {path: 'products', loadChildren: () => ProductsModule}, // where im trying to load my products module from the main module
            {path: 'home', component: HomeComponent},
            {path: 'about', component: AboutComponent},
            {path: 'api', component: ApiComponent},
            {path: 'status', component: StatusComponent},
            {path: 'support', component: SupportComponent},
            {path: 'customers', component: CustomersComponent},
            {path: 'jobs', component: JobsComponent},
            {path: 'tos', component: TosComponent},
            {path: 'signup', component: SignupComponent, canActivate: [AuthGuard]},
            {path: 'logout', component: LogoutComponent, canActivate: [AuthGuard]},
            {path: 'login', component: LoginComponent},
            {path: 'error', component: ErrorComponent, canActivate: [ErrorService]},
            {path: "404", component: NotFoundComponent},
            {path: '', redirectTo: '/home', pathMatch: 'full'},
        ]
    },
    {path: "admin", loadChildren: "./admin/admin.module#AdminModule"},
    {path: '**', redirectTo: '/404'}
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule {}

products.module.ts [我试图加载子路由的主要产品模块]

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        SharedModule,
        RouterModule,
        ProductsRoutingModule
    ],
    declarations: [ProductsComponent, OverviewComponent, IntroComponent, NavigationComponent, ProductComponent],
    exports: [
        ProductsComponent, OverviewComponent, IntroComponent, NavigationComponent, ProductComponent, RouterModule, ProductsRoutingModule
    ]
})
export class ProductsModule {
}

products-routing.module.ts [产品子模块路由器]

export const productRoutes: Routes = [
    {
        path: '',
        component: ProductsComponent,
        children: [
            {
                path: 'overview',
                component: OverviewComponent,
            },
            {
                path: 'intro',
                component: IntroComponent
            },
            {
                path: 'product/:product',
                component: ProductComponent
            },
            {
                path: '',
                redirectTo: '/products/intro',
                pathMatch: 'full'
            },
            {
                path: '**',
                redirectTo: '/404',
                pathMatch: 'full'
            }
        ]
    }
];

@NgModule({
    imports: [RouterModule.forChild(productRoutes)],
    exports: [RouterModule]
})
export class ProductsRoutingModule {}

products.component.html [带产品子组件插座的产品模板]

<h1>Products</h1>

<app-product-navigation></app-product-navigation>
<router-outlet></router-outlet>

navigation.component.html [app-product-navigation组件模板]

<nav class="navbar navbar-info" role="navigation">
  <div class="container-fluid">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#products-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>

    <div class="collapse navbar-collapse" id="products-navbar-collapse">
      <ul class="nav navbar-nav">
        <li routerLinkActive="active"><a routerLink="/products/intro">Intro</a></li>
        <li routerLinkActive="active"><a routerLink="/products/overview">Overview</a></li>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Products <b class="caret"></b></a>
          <ul class="dropdown-menu">
            <li routerLinkActive="active"><a routerLink="/products/product/reflex">Reflex</a></li>
            <li routerLinkActive="active"><a routerLink="/products/product/override">Project Override</a></li>
          </ul>
        </li>
      </ul>
    </div>
  </div>
</nav>

我还将提供我的package.json版本依赖项,我正在使用ng服务进行测试 .

"dependencies": {
    "@agm/core": "1.0.0-beta.0",
    "@angular/animations": "4.3.1",
    "@angular/cdk": "2.0.0-beta.10",
    "@angular/common": "4.3.1",
    "@angular/compiler": "4.3.1",
    "@angular/core": "4.3.1",
    "@angular/forms": "4.3.1",
    "@angular/http": "4.3.1",
    "@angular/material": "2.0.0-beta.10",
    "@angular/platform-browser": "4.3.1",
    "@angular/platform-browser-dynamic": "4.3.1",
    "@angular/platform-server": "4.3.1",
    "@angular/router": "4.3.1",
    "angular2-material-datepicker": "0.5.0",
    "animate.css": "3.5.2",
    "arrive": "2.3.1",
    "bootstrap": "3.3.5",
    "bootstrap-material-design": "0.5.10",
    "bootstrap-notify": "3.1.3",
    "bootstrap-select": "1.12.2",
    "bootstrap-tagsinput": "0.7.1",
    "chartist": "0.9.4",
    "chartist-plugin-zoom": "0.4.0",
    "core-js": "2.4.1",
    "datatables": "1.10.12",
    "datatables.net-bs": "1.10.12",
    "datatables.net-responsive": "2.1.1",
    "eonasdan-bootstrap-datetimepicker": "4.17.47",
    "fullcalendar": "3.4.0",
    "googleapis": "19.0.0",
    "jasny-bootstrap": "3.1.3",
    "jquery": "1.12.4",
    "moment": "2.18.1",
    "moment-timezone": "0.4.0",
    "ng2-nouislider": "1.6.1",
    "ng2-select": "1.2.0",
    "ngx-chips": "1.4.6",
    "nouislider": "9.2.0",
    "rxjs": "^5.4.2",
    "twitter-bootstrap-wizard": "1.2.0",
    "typescript": "2.3.4",
    "validate": "3.0.1",
    "web-animations-js": "2.2.2",
    "zone.js": "0.8.4"
  },
  "devDependencies": {
    "@angular/cli": "1.4.2",
    "@angular/compiler-cli": "4.3.1",
    "@types/bootstrap": "3.3.32",
    "@types/chartist": "0.9.34",
    "@types/jasmine": "2.5.38",
    "@types/jquery": "1.10.31",
    "@types/node": "6.0.73",
    "codelyzer": "2.0.0",
    "jasmine-core": "2.5.2",
    "jasmine-spec-reporter": "3.2.0",
    "karma": "1.4.1",
    "karma-chrome-launcher": "2.0.0",
    "karma-cli": "1.0.1",
    "karma-coverage-istanbul-reporter": "0.2.0",
    "karma-jasmine": "1.1.0",
    "karma-jasmine-html-reporter": "0.2.2",
    "node-sass": "^4.5.3",
    "protractor": "5.1.0",
    "ts-node": "2.0.0",
    "tslint": "4.5.0",
    "typescript": "2.3.4"
  }
}

这是我在stackoverflow上的第一个'寻求帮助'的帖子,所以让我知道我有什么可以提高的 .

我试图研究各种形式和教程,并参考了angular docs for routing

编辑:添加一些图片以进一步说明情况

主页:http://prntscr.com/gskex5

产品[/ products / intro](导航到使用routerLink):http://prntscr.com/gskf2h(缺少产品导航栏)刷新时,导航栏变为可见,但介绍组件消失了:http://prntscr.com/gskfaq

但是,当我点击产品导航中的另一个组件时,它可以正常工作:http://prntscr.com/gskfhf

如果我刷新,组件消失,导航器就会离开:http://prntscr.com/gskfna现在,无论出于何种原因,如果我回到介绍,它都能正常工作:http://prntscr.com/gskfra

所以基本上,无论在最初加载页面时加载什么路由,它都会出现问题[组件不可见] . 如果最初加载的路线不是/ products;产品导航栏不可见 .

1 回答

  • 0

    对于这种相当奇怪的情况,我能够通过使用angular-cli生成一个新的Angular 4应用程序来修复这种奇怪的行为: ng new

    我猜它与我正在运行的Angular版本有关 .

    对于我的新项目, @angular 版本设置为** ^ 4.0.0 * .

    在旧项目中,版本设置为4.3.1

    我猜它与v4.3.1的错误修正中的一个变化有关:

    router:canDeactivate guards应该从下到上运行(1ac78bf),关闭#15657路由器:当配置发生变化时应该导航到同一个url(4340bea),关闭#15535路由器:应该同时运行同一路径的解析器(ec89f37),关闭#14279路由器:自定义匹配器中的终端路由(5d275e9)

    TL;DR

    使用最新的稳定版ng4

相关问题