Angular: Как повторно визуализировать дочерний компонент на основе изменения маршрута родительского компонента приложения? - PullRequest
0 голосов
/ 01 апреля 2020

Мое приложение отображает компонент проекта, который содержит информацию о данном идентификаторе из URL-адреса, например my.app/project/foo.

Компонент приложения:

  • использует <router-outlet> для визуализации компонент проекта
  • содержит список всех проектов для перехода к каждому проекту

Проблема заключается в следующем: при нажатии на ссылку маршрут правильно изменяется с идентификатором проекта, но компонент проекта не выполняет повторную визуализацию на основе нового идентификатора. После перезагрузки компонента проекта отображается правильно, но не после нажатия на другой идентификатор.

app.routing.module.ts:

const routes: Routes = [
...
  {
    path: 'project/:key',
    loadChildren: () =>
      import('../project-page/project-page.module').then(
        m => m.ProjectPageModule
      )
  }
...
];

app.component. html:

<a routerLink="/project/{{ project.id }}" *ngFor="let project of projects">
  {{ project.name }}
</a>
...
<div class="content">
  <router-outlet></router-outlet>
</div>

project-page.component.ts (внутри ProjectPageModule ):

export class ProjectPageComponent implements OnInit {

  project: any;

  ngOnInit(): void {
    const id = this.route.snapshot.paramMap.get('id');

    return this.projectService
      .getProjectById(id)
      .pipe(delay(1000) /* debug only */)
      .subscribe(response => this.project = response);
    );
  }
  ...
}

project-page.component. html:

<h1>{{ project.id }}</h1>

Я не уверен, если

  • приложение Компонент должен «инициировать» новый рендеринг компонента проекта или, возможно, передать параметр id из URL-адреса в качестве «ввода» компоненту проекта ... или ...
  • * 1034 Компонент * project должен прослушивать изменения маршрута иначе, чем моя текущая реализация со снимком маршрута.

Как вы думаете?

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Я пришел к выводу, что дочерний компонент должен прослушивать изменения маршрута в своем методе ngOnInit:

  ngOnInit(): void {
    this.route.params.subscribe((param) => {
      this.getProjectFromUrl(param.id);
    });
  }

  getProjectFromUrl(id: number): any {
    return this.projectService
      .getProjectById(id)
      .pipe(delay(1000) /* debug only */)
      .subscribe(response => this.project = response);
    );
  }

Yay!

0 голосов
/ 01 апреля 2020

Вы должны разделить ваши маршруты, чтобы app.routing.module содержал только:

const routes: Routes = [
...
  {
    path: 'project',
    loadChildren: () =>
      import('../project-page/project-page.module').then(m => m.ProjectPageModule)
  }
...
];

Затем создайте другой модуль маршрутизации, например project-page.routing.module, и импортируйте его в ваш ProjectPageModule. Маршруты для вашего подмодуля могут быть определены следующим образом:

const appRoutes: Routes = [
    {
        path: '',
        component: ProjectPageEntryComponent,
        children: [
            {
                path: ':id',
                component: ProjectPageComponent
            }
        ]
    }
];

@NgModule({
    imports: [RouterModule.forChild(appRoutes)],
    exports: [RouterModule]
})
export class ProjectPageRoutingModule {}

и, наконец, код для ProjectPageEntryComponent будет выглядеть примерно так:

@Component({
    template: '<router-outlet></router-outlet>'
})
export class ProjectPageEntryComponent {}

Таким образом, вы обрабатываете только высокоуровневые Навигации в вашей основной app.routing.module и более конкретные навигации для любых SpecificModule связанных навигаций в отдельном файле.

...