Angular 5 Parent перезагружается при изменении дочернего маршрута - PullRequest
0 голосов
/ 04 мая 2018

У меня проблема с тем, что мой родительский компонент (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;
      });
  }
}

Ответы [ 3 ]

0 голосов
/ 20 июня 2018

Я считаю, что это ошибка, как упомянуто здесь: https://github.com/angular/angular/issues/18374

0 голосов
/ 25 февраля 2019

да, canActivateChild перезагружает весь родительский компонент при переключении между дочерними маршрутами

0 голосов
/ 14 мая 2018

Я исправил проблему, переместив вызов API в службу с переменной там и загрузив данные только в том случае, если они еще не установлены или через переменную force пропущены.

...