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

时间:2017-10-03 02:57:01

标签: javascript node.js twitter-bootstrap angular typescript

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

  • angular 4控制台或javascript控制台中没有错误
    • 使用Angular CLI(Angular 4)

我使用角度路由器获得了非常奇怪的行为。我正在尝试从父AppModule加载子路由,它有自己的模块。路线位于/ products

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

  1. /产品/概述
  2. / products / intro [重定向到/ products]
  3. /产品/产品/:产品
  4. 产品模块应该拥有自己的导航栏,位于全局AppModule的导航栏上,导航栏位于products.component.html组件模板的路由器插座上方。

    主要问题:当我将页面(不使用角度routerLink)加载到/ products:

    • 两个导航栏都可见
    • LOADED(ex / intro)页面的导航栏可见,但子组件(IntroComponent) NOT 可见
    • 然而,当我导航到/ products模块路径中的任何其他子路径时(例如/ overview或/ product /:product):它渲染得很好。因此,无论在整页上加载什么路线都不可见。

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

    • 导航栏不可见 ?????
    • 子组件(ex / intro组件)是可见的

    过去几天,这让我感到非常痛苦。

    现在,一些代码:

    app.module.ts [主要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 { }
    

    应用-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>
    <br/>
    <app-product-navigation></app-product-navigation>
    <br/>
    <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>
    <br/>
    

    我还将提供我的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 :(得分:1)

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

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

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

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

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

  
      
  • 路由器:canDeactivate后卫应该从下到上运行(1ac78bf),   关闭#15657
  •   
  • 路由器:应该在配置时导航到相同的URL   更改(4340bea),关闭#15535
  •   
  • 路由器:应该运行解析器   同时路线(ec89f37),关闭#14279
  •   
  • 路由器:终端   自定义匹配器中的路由(5d275e9)
  •   

TL; DR

使用最新稳定版本的ng4