Angular 2 Управление маршрутизатором с помощью дочерних маршрутов

При использовании дочерних маршрутов с angular2 маршрутизатором "3.0" нет необходимости объявлять их в конфигурации родительского маршрутизатора (раньше вам нужно было сделать что-то вроде /child... в родительском компоненте).

Я хочу настроить глобальный обработчик "страницы не найден", который я могу сделать следующим образом:

{ path: '**', component: PageNotFoundComponent }

в модуле маршрутизации приложения.

Предостережение. Если я это сделаю, маршрутизатор перейдет к маршрутам, объявленным в модуле маршрутизации приложения, до того, как PageNotFoundComponent будет просто отлично. Но он всегда переходит к шаблону подстановки, когда я пытаюсь получить доступ к дочернему маршруту (объявлен с использованием RouterModule.forChild в некотором дочернем модуле маршрутизации.

Интуитивно, маршрут подстановочного знака должен быть размещен за всеми другими конфигурациями маршрутов, поскольку маршрутизатор разрешается в порядке объявления. Но, похоже, не существует способа объявить его после того, как маршруты ребенка. Также не очень элегантно объявлять маршрут подстановки в всех дочерних модулях маршрутизатора.

Мне что-то не хватает или нет способа определить глобальную 404-страничную страницу в Angular -2-Router-3 при использовании дочерних маршрутов?

Ответы

Ответ 1

Вы можете легко иметь централизованный шаблон подстановочного знака, т.е. для компонента "Страница не найдена на сайте". Он просто должен быть извлечен в отдельный модуль маршрутизации, который включается после всех остальных модулей, содержащих дочерние маршруты.

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

Модуль маршрутизации подстановки или модуль страницы не найден:

@NgModule({
    imports: [
        RouterModule.forChild([
            {
                path: '**',
                component: NotFoundComponent
            }
        ])
    ],
    declarations: [
        NotFoundComponent
    ],
    exports: [
        RouterModule
    ]
})
export class WildcardRoutingModule { }

Модуль приложения:

@NgModule({
    imports: [
        BrowserModule,

        AppRoutingModule, // Has forRoot routes 

        HomeModule, // Has forChild routes 
        LoginModule, // Has forChild routes
        ProductModule, // Has forChild routes
        DiagnosticsModule, // Has forChild routes

        WildcardRoutingModule // Last position
    ],
    declarations: [
        AppComponent  
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

Ответ 2

Простым решением является переупорядочение модулей в массиве "import" в файле модуля приложения - убедитесь, что app/root router является последним элементом массива; например,

@NgModule({
  imports: [FeatureModule1, FeatureModule2, FeatureModule3, AppRouterModule]
  ...
  ...
})

Ответ 3

У меня есть следующий пример для вас. / -route перенаправляет в /app -route и показывает StartComponent внутри <router-outlet> вашего родительского AppComponent. Сам StartComponent имеет в своем шаблоне другой <router-outlet> в который маршрутизатор загружает дочерние компоненты.

const appRoutes: Routes = [
    {
        path: '',
        redirectTo: 'app',
        pathMatch: 'full',
    },
    {
        path: 'app',
        component: StartComponent,
        children: [
            {
                path: '',
                redirectTo: 'welcome'
            },
            {
                path: 'welcome',
                component: WelcomeComponent
            },
            {
                path: 'settings',
                component: SettingsComponent
            },            
        ]
    },
    {
        path: '**',
        component: PageNotFoundComponent 
    }    
];

Последний маршрут - это маршрутный символ с ** -path. Это будет показано, если вы перейдете к неизвестному URL-адресу, например /test123 или для дочерних компонентов /app/test123.

pathMatch: 'full' означает, что маршрутизатор ищет равный маршрут. Это важно для перенаправлений.

Если вам также нужен PageNotFoundComponent для ваших детей, вы также можете добавить к ним подстановочный знак.

{
    path: 'app',
    component: StartComponent,
    children: [
        {
            path: '',
            redirectTo: 'welcome'
        },
        {
            path: 'welcome',
            component: WelcomeComponent
        },    
        {
            path: '**',
            component: ChildrenPageNotFoundComponent
        },      
    ]
}