簡體   English   中英

Angular 4 路由奇怪的行為:除非頁面刷新,否則不呈現子模塊

[英]Angular 4 routing weird behavior: not rendering child module unless on page refresh

我一直在尋找解決這種奇怪行為的方法,但沒有運氣。

  • angular 4 控制台或 javascript 控制台中沒有錯誤
    • 使用 Angular CLI (Angular 4)

我對角度路由器的行為非常奇怪。 我正在嘗試從父 AppModule 加載具有自己模塊的子路由。 路線在/products

在 /products 模塊(products.module.ts):我有 3 條路線:

  1. /產品/概述
  2. /products/intro [重定向到 /products]
  3. /產品/產品/:產品

products 模塊應該在全局 AppModule 的導航欄下有自己的導航欄,它位於 products.component.html 組件模板中的路由器插座上方。

主要問題:當我將頁面(不使用有角度的 routerLink)加載到 /products 時:

  • 兩個導航欄都可見
  • 加載的頁面(ex /intro)具有可見的導航欄,但子組件(IntroComponent)可見
  • 但是,當我導航到 /products 模塊路由中的任何其他子路由時,(例如 /overview 或 /product/:product):它呈現得很好。 因此,在整頁刷新時加載的任何路由都是不可見的。

最奇怪的部分:當我在不是 /products(例如 /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 { }

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>
<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 serve 進行測試。

  "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; 產品導航欄不可見。

對於這種相當奇怪的情況,我能夠通過使用 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; 博士

使用最新的穩定版 ng4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM