Angular 4 路由器在 RouterLink 导航时追加组件而非销毁它们。

3
当从子路由中的子模块导航到另一个同级子路由时,路由器不会销毁先前的组件,而是在前进和后退导航时附加新组件。
为什么会这样?
/#/subscriber/lookup开始,移动到 /#/subscriber/register 路由。
<a [routerLink]="['../register']">Subscriber register link</a>

app.routes.ts

/**
 * Angular 2 decorators and services
 */

import { Routes } from '@angular/router';

/**
 * Other services
 */
import { RouteProtection } from '../services/route-protection.service';
// import { DataResolver } from './app.resolver';

/**
 * Imported Components
 */
import { LoginComponent } from '../login/login.component';
import { NotFound404Component } from '../404/notfound404.component';

export const ROUTES: Routes = [{
   path: '',
   redirectTo: 'subscriber',
   pathMatch: 'full',
}, {
   path: 'subscriber',
   loadChildren: '../+subscriber/subscriber.module#SubscriberModule',
   // canActivate: [RouteProtection]
}, {
   path: 'detail',
   loadChildren: '../+detail/detail.module#DetailModule',
   canActivate: [RouteProtection]
}, {
   path: 'login',
   component: LoginComponent
}, {
   path: '**',
   component: NotFound404Component
}, {
   path: '404',
   component: NotFound404Component
}];

// export const routing = RouterModule.forRoot(ROUTES, { useHash: true});

subscriber.routes.ts

/**
 * Imported Components
 */
import { SubscriberLookupComponent } from './lookup/subscriber-lookup.component';
import { SubscriberRegisterComponent } from './register/subscriber-register.component';

/*
 * Shared Utilities & Other Services
 */
// import { RouteProtection } from '../services/route-protection.service';
// import { DataResolver } from '../services/app.resolver';

export const subscriberRoutes = [{
   path: '',
   children: [{
      path: '',
      pathMatch: 'full',
      redirectTo: 'lookup'
   }, {
      path: 'lookup',
      component: SubscriberLookupComponent, //canActivate: [RouteProtection],
   }, {
      path: 'register',
      component: SubscriberRegisterComponent, //canActivate: [RouteProtection],  // resolve: {      'dataBroughtToComponent': DataResolver   }
   }]

},];

app.module.ts

/**
 * `AppModule` is the main entry point into Angular2's bootstraping process
 */
@NgModule({
   bootstrap: [AppComponent],
   declarations: [ // declarations contains: components, directives and pipes

      // Components
      AppComponent, LoginComponent, NotFound404Component, // Directives
      NavSidebarComponent, NavHeaderComponent, NavFooterComponent

      // Pipes

   ],
   imports: [ // import other modules
      BrowserModule, SharedModule, BrowserAnimationsModule, RouterModule.forRoot(ROUTES, {useHash: true}), NgbModule.forRoot()
      /*      ApplicationInsightsModule.forRoot({
               instrumentationKey: '116b16e7-0307-4d62-b201-db3ea88a32c7'
            })*/

   ],
   providers: [ // expose our Services and Providers into Angular's dependency injection
      ENV_PROVIDERS, APP_PROVIDERS, AUTH_PROVIDERS]
})

subscriber.module.ts

@NgModule({
   imports: [
      SharedModule,
      CommonModule,
      RouterModule.forChild(subscriberRoutes)
   ],
   declarations: [ // Components / Directives / Pipes
      SubscriberLookupComponent,
      SubscriberRegisterComponent
   ],
   // exports: [
   //    SharedModule,
   //    SubscriberLookupComponent,
   //    SubscriberRegisterComponent
   // ]
})

在导航时会发生以下情况:

追加路由


你能否使用 Plunker 重现此问题? - Aravind
很复杂,一次在 Plunker 上重现一个文件,我会尝试。 - TetraDev
你能在TeamViewer上面继续调试吗? - Aravind
好的,我已经设置好了,让我们尝试连接。有私人聊天吗? - TetraDev
让我们在聊天中继续这个讨论 - TetraDev
显示剩余2条评论
2个回答

4
我曾经遇到过同样的问题。后来我发现,当我的新组件被创建时,它会抛出异常,然后我的旧组件就没有被销毁。
在我的情况下,在模板中我有{{model.field}},在TypeScript中有model: Model;,但是当组件被创建时,modelundefined。我认为如果在创建组件时抛出任何异常,路由器就无法销毁旧组件。
我使用Visual Studio Code调试器找到了异常的原因。
所以我只是添加了一个*ngIf来检查模型:
<tag *ngIf="model">
    {{model.field}}
</tag>

谢谢!我没有意识到我的组件会抛出错误,但你是对的。如果组件A抛出错误,那么尝试导航到组件B将阻止路由器销毁组件A。这一定是一个Angular的bug。 - TetraDev

2
起初我认为这是因为我通过BrowserSync查看我的angular应用程序。似乎由于BrowserSync的JavaScript与Angular的路由器产生了某种干扰。我认为这是一个bug。当我直接查看我的应用程序时,路由器按预期工作。
然而,后来在没有BrowserSync的情况下,它再次发生了。
Caio Filipe的答案解决了我的问题。原因是我的组件A出现了错误,因此在导航到组件B时,由于错误无法销毁组件A。我向Angular提交了一张工单

2
这是同一个问题的另一张票:https://github.com/angular/angular/issues/19093。与此同时,严重性已经增加,希望很快能够解决。 - Francesco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接