Angular 5 当子路由改变时父重载

Angular 5 Parent reloads when Child route changes

我遇到一个问题,每次子组件之一更改(子路由更改)时我的父组件 (LoggedInComponent) 都会重新加载。

我四处寻找答案,但似乎找不到适合我情况的答案。

这是我的app-routing.module.ts

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  {
    path: '', component: LoggedInComponent, canActivateChild: [AuthGuard], children: [
      { path: '', redirectTo: 'home', pathMatch: 'full' },
      { path: 'home', component: DashboardComponent },

      { path: 'groups', component: GroupsComponent, data: { role: [PermissionEnum.Groups_View] } },
      { path: 'groups/edit/:id', component: GroupDetailComponent, data: { role: [PermissionEnum.Groups_Edit] } },
      { path: 'groups/create', component: GroupDetailComponent, data: { role: [PermissionEnum.Groups_Create] } },

      { path: 'users', component: UsersComponent, data: { role: [PermissionEnum.Users_View] } },
      { path: 'users/edit/:id', component: UserDetailComponent, data: { role: [PermissionEnum.Users_Edit] } },
      { path: 'users/create', component: UserDetailComponent, data: { role: [PermissionEnum.Users_Create] } },

      { path: 'profile', component: ProfileComponent },
      { path: 'profile/:tabindex', component: ProfileComponent },

      { path: 'settings', component: SettingComponent, data: { role: [PermissionEnum.Global_Settings_View] } },

      { path: 'external-login/:result', component: ExternalLoginProvidersComponent },

      { path: 'permissions/:id/:type', component: PermissionsComponent, data: { role: [PermissionEnum.Users_AssignPermissions] } },
      { path: 'permission-denied', component: PermissionDeniedComponent },

      { path: 'reference-data/:type', component: ReferenceDataComponent, data: { role: [PermissionEnum.Sms_Template_View] } },
      { path: 'reference-data/:type/edit/:id', component: ReferenceDataDetailsComponent, data: { role: [PermissionEnum.Sms_Template_Edit] } },
      { path: 'reference-data/:type/create', component: ReferenceDataDetailsComponent, data: { role: [PermissionEnum.Sms_Template_Create] } },

      { path: 'tenants', component: TenantsComponent, data: { role: [PermissionEnum.Tenant_View] } },
      { path: 'tenants/edit/:id', component: TenantDetailComponent, data: { role: [PermissionEnum.Tenant_Edit] } },
      { path: 'tenants/create', component: TenantDetailComponent, data: { role: [PermissionEnum.Tenant_Create] } },

      { path: 'sms-campaigns', component: SmsCampaignsComponent, data: { role: [PermissionEnum.SmsCampaign_View] } },
      { path: 'sms-campaigns/create', component: CreateSmsCampaignComponent, data: { role: [PermissionEnum.SmsCampaign_Create] } },
      { path: 'sms-campaigns/details/:id', component: SmsCampaignDetailsComponent, data: { role: [PermissionEnum.SmsCampaign_View] } },

      { path: 'document-library', component: LibraryDocumentsComponent },

      { path: 'report-management', component: ReportManagementComponent },
      { path: 'report-management/create', component: CreateReportComponent },
      { path: 'report-management/:id', component: IdpComponent },
      { path: 'report-management/edit/:id', component: ReportDetailsComponent },
      { path: 'report/:reportName', component: ReportComponent }
    ]
  }
];

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

我的 app.component.html 中有主路由器插座,登录后将带您到 LoggedInComponenet,其中有页眉、页脚、左侧菜单和另一个用于儿童的路由器插座。

这是我的LoggedIn.componenent.html

<app-header></app-header>
<div class="m-grid__item m-grid__item--fluid m-grid m-grid--ver-desktop m-grid--desktop m-body">
  <app-left-menu></app-left-menu>
  <div *ngIf="loading">
    <app-loading-indicator></app-loading-indicator>
  </div>
  <div class="center-display" *ngIf="childrenLoadingAllowed">
    <router-outlet class="m-grid__item m-grid__item--fluid m-wrapper" [ngClass]="{ hidden: loading }"></router-outlet>
  </div>
</div>
<app-footer></app-footer>

然后我有我的LoggedIn.component.ts

import { Component, OnInit } from '@angular/core';
import { BaseComponent } from '../shared/base.component';

@Component({
  selector: 'app-logged-in',
  templateUrl: './logged-in.component.html',
  styleUrls: ['./logged-in.component.css']
})
export class LoggedInComponent extends BaseComponent implements OnInit {

  public loading = true;
  public childrenLoadingAllowed = false;

  constructor() {
    super();
  }

  ngOnInit() {
    this.layoutService.setLoadingEvent
      .subscribe((res: boolean) => {
        if (this.loading !== res)
          this.loading = res;
      });
  }
}

最后是左侧菜单,当我加载子项时它会不断重新加载

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { BaseComponent } from '../../shared/base.component';
import { PermissionEnum, LookupClient, LookupType, LookUpDto } from '../../../services/web-api-generated';

@Component({
  selector: 'app-left-menu',
  templateUrl: './left-menu.component.html',
  styleUrls: ['./left-menu.component.scss'],
  encapsulation: ViewEncapsulation.None
})

export class LeftMenuComponent extends BaseComponent implements OnInit {

  public hasReports = false;

  public reports: Array<LookUpDto> = new Array<LookUpDto>();

  constructor(private lookupClient: LookupClient) {
    super();

    this.loadReportMenuItems();
  }

  ngOnInit() {
    this.layoutService.rebuildReportMenu
      .subscribe(res => {
        this.loadReportMenuItems();
      });
  }

  private loadReportMenuItems(): void {
    this.lookupClient.getLookUpValues(LookupType.MunicipalReports)
      .subscribe((res: Array<LookUpDto>) => {
        this.reports = res;

        this.reports.forEach(element => {
          element.value = element.value.replace(/\s+/g, '-').toLocaleLowerCase();
        });

        this.hasReports = res.length > 0;
      });
  }
}

我解决了这个问题,方法是将 api 调用移动到一个带有变量的服务,并且只在数据尚未设置或传递了强制变量时才加载数据。

我认为这是此处提到的错误:https://github.com/angular/angular/issues/18374

是的,canActivateChild 在子路由之间切换时重新加载整个父组件