无法找到加载“LocalizationListComponent"的主要出口 [英] Cannot find primary outlet to load 'LocalizationListComponent'

查看:25
本文介绍了无法找到加载“LocalizationListComponent"的主要出口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 Angular 2 RC5 应用程序,并且每个模块都是延迟加载的.当应用程序启动时,它会按预期显示来自 LocalizationListComponent 的列表,但控制台中有一条消息说无法找到加载LocalizationListComponent"的主要出口.考虑到显示列表和报错的那个组件很奇怪很不正常.

为了解决这个问题,我需要将 ROUTER_DIRECTIVES 添加到每个受此错误影响的组件和视图中.这样做的问题是列表将显示两次,并且详细信息屏幕会加载到此列表下.这不是我想要的行为.

在此之后,我浏览了 angular.io 上的 Angular 2 Routing 教程,并检查了他们的 plunker 代码.一切似乎都相同,但错误仍然存​​在.

我已将应用程序上传到保管箱(无效链接)

以下是模块、路由和组件(对于长长的列表,我深表歉意):

app.routes.ts

import { Routes, RouterModule } from "@angular/router";const 路由:路由 = [{小路: "",重定向到:/本地化",路径匹配:完整"},{路径:本地化",loadChildren: "./app/modules/localization/localization.module",}];export const appRoutes = RouterModule.forRoot(routes);

app.module.ts

import { NgModule } from "@angular/core";从@angular/platform-b​​rowser"导入 { BrowserModule };从../routes/app.routes"导入 { appRoutes }import { AppComponent } from "../components/app.component";import { AppNavigationComponent } from "../components/app-navigation.component";import { AppStartComponent } from "../components/app-start.component";import { LoggerModule } from "./logging/logger.module";import { SharedModule } from "./shared/shared.module";@NgModule({进口:[ BrowserModule, LoggerModule.forRoot(), SharedModule, appRoutes ],声明:[ AppComponent, AppNavigationComponent, AppStartComponent ],引导程序:[ AppComponent ]})导出类 AppModule {}

app.component.ts

///import { Component, OnInit, OnDestroy } from "@angular/core";从@angular/router"导入 { ActivatedRoute, Router, ROUTER_DIRECTIVES };import { AppNavigationComponent } from "./app-navigation.component";import { LoggerMessageType } from "../modules/logging/models/enums/LoggerMessageType";import { AbstractLogger } from "../modules/logging/interfaces/AbstractLogger";@成分({模块 ID:module.id,选择器:vms-localization-app",templateUrl: "../views/app.component.html",指令:[ ROUTER_DIRECIVES ]})导出类 AppComponent {状态:字符串;构造函数(私有记录器:AbstractLogger){this.status = "Alpha 0.1";}ngOnInit() : 任何 {}ngOnDestroy() : 任何 {}}

localization.module.ts

import { NgModule } from "@angular/core";从@angular/router"导入 { RouterModule };从@angular/common"导入 { CommonModule };从@angular/forms"导入 { FormsModule };import { localizationRoutes } from "./routes/localization.routes";import { LocalizationListComponent } from "./components/localization-list.component";import { LocalizationDetailsComponent } from "./components/localization-details.component";import { AbstractLocalizationService } from "./interfaces/AbstractLocalizationService";import { MockLocalizationService } from "./services/mock-localization.service";@NgModule({进口:[ localizationRoutes, CommonModule, FormsModule, RouterModule ],声明:[ LocalizationListComponent, LocalizationDetailsComponent ],提供者:[{提供:AbstractLocalizationService,useClass:MockLocalizationService}]})导出默认类 LocalizationModule {}

localization.routes.ts

import { Routes, RouterModule } from "@angular/router";import { LocalizationListComponent } from "../components/localization-list.component";import { LocalizationDetailsComponent } from "../components/localization-details.component";const 路由:路由 = [{小路: "",组件:LocalizationListComponent,孩子们: [{路径:本地化",组件:LocalizationListComponent},{路径: ":id",组件:LocalizationDetailsComponent},{小路: "",组件:LocalizationListComponent}]}];export const localizationRoutes = RouterModule.forChild(routes);

localization-list.component.ts

import { Component, OnInit } from "@angular/core";从'../models/localization'导入{本地化};从../models/language"导入{语言};import { AbstractLocalizationService } from "../interfaces/AbstractLocalizationService";import { AbstractLogger } from "../../logging/interfaces/AbstractLogger";import { LoggerMessageType } from "../../logging/models/enums/LoggerMessageType";@成分({模块 ID:module.id,选择器:本地化列表",templateUrl: "../views/localization-list.component.html"})导出类 LocalizationListComponent 实现 OnInit {本地化:本地化[];语言:语言[];构造函数(私有本地化服务:AbstractLocalizationService,私人记录器:AbstractLogger) {}ngOnInit() : 任何 {this.localizationService.getLocalizations().subscribe((result: Localization[]) => {this.localizations = 结果;this.languages = this.localizations[0].languages;});}}

app.component.html

<div class="page-header"><h1>VMS本地化<small>{{ status }}</small></h1><app-navigation></app-navigation>

<路由器插座></路由器插座>

上面的片段(和提供的项目)肯定有问题,但我看不到任何一个.

我还在 StackOverflow 上检查了其他问题,但它们主要是处理我在 app.component.ts 中缺少的 ROUTER_DIRECTIVES

感谢大家的帮助!

解决方案

我刚刚在 GitHub 上遇到一个问题 (https://github.com/angular/angular/issues/10686),其中解释说这是一种有意的行为.每个拥有 children 的父级(对于 loadChildren 似乎也是如此)必须有自己的出口来加载子级.

路由器文档中似乎没有任何记录.

更新:当您在模块的路由器中声明 children 时,每个父级都必须拥有自己的 才能加载这些子级.如何实现这取决于需求.对于我的解决方案,我创建了一个空组件,它只包含 并定义如下路由:

import { Routes, RouterModule } from "@angular/router"从./app/modules/SomeModule/SomeParentComponent"导入 { SomeParentComponent }从./app/modules/SomeModule/SomeChild1Component"导入 { SomeChildComponent1 }从./app/modules/SomeModule/SomeChild2Component"导入 { SomeChildComponent2 }const 路由:路由 = [小路: "",组件:SomeParentComponent,孩子们: [{小路: "",组件:SomeChild1Component},{路径: ":id",组件:SomeChild2Component}]]export const someModuleRoutes = RouterModule.forChild(routes);

这应该可以解决问题,因为主要组件路由将调用 loadChildren 指向 SomeParentComponent.

I am creating an Angular 2 RC5 application and every module is lazy loaded. When the application starts it displays the list from LocalizationListComponent, as intended, but there is a message in the console which says Cannot find primary outlet to load 'LocalizationListComponent'. Considering that the list is displayed and the error complains about the very component is very strange and unusual.

In order to resolve this I need to add <router-outlet> together with ROUTER_DIRECTIVES to every component and view that is affected by this error. The problem with this is that the list will be presented twice and the details screen is loaded under this list. This is not the behavior I want.

After this I went through Angular 2 Routing tutorial on angular.io and I checked their plunker code. Everything seems to be identical, but the error persists.

I've uploaded the application to dropbox (inactive link)

Here are the modules, routes and components (I apologize for the long list):

app.routes.ts

import { Routes, RouterModule } from "@angular/router";

const routes: Routes = [
    {
        path: "",
        redirectTo: "/localizations",
        pathMatch: "full"
    },
    {
        path: "localizations",
        loadChildren: "./app/modules/localization/localization.module",
    }
];

export const appRoutes = RouterModule.forRoot(routes);

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { appRoutes } from "../routes/app.routes"

import { AppComponent } from "../components/app.component";
import { AppNavigationComponent } from "../components/app-navigation.component";
import { AppStartComponent } from "../components/app-start.component";

import { LoggerModule } from "./logging/logger.module";
import { SharedModule } from "./shared/shared.module";

@NgModule({
    imports: [ BrowserModule, LoggerModule.forRoot(), SharedModule, appRoutes ],
    declarations: [ AppComponent, AppNavigationComponent, AppStartComponent ],
    bootstrap: [ AppComponent ]
})
export class AppModule {

}

app.component.ts

/// <reference path="../../typings/globals/node/index.d.ts" />

import { Component, OnInit, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router, ROUTER_DIRECTIVES } from "@angular/router";
import { AppNavigationComponent } from "./app-navigation.component";

import { LoggerMessageType } from   "../modules/logging/models/enums/LoggerMessageType";
import { AbstractLogger } from "../modules/logging/interfaces/AbstractLogger";

@Component({
    moduleId: module.id,
    selector: "vms-localization-app",
    templateUrl: "../views/app.component.html",
    directives: [ ROUTER_DIRECTIVES ]
})
export class AppComponent {
    status: string;

    constructor(private logger: AbstractLogger) {
        this.status = "Alpha 0.1";
    }

    ngOnInit() : any {

    }

    ngOnDestroy() : any {

    }
}

localization.module.ts

import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import { CommonModule } from "@angular/common";
import { FormsModule } from "@angular/forms";
import { localizationRoutes } from "./routes/localization.routes";

import { LocalizationListComponent } from "./components/localization-list.component";
import { LocalizationDetailsComponent } from "./components/localization-details.component";

import { AbstractLocalizationService } from "./interfaces/AbstractLocalizationService";
import { MockLocalizationService } from "./services/mock-localization.service";

@NgModule({
    imports: [ localizationRoutes, CommonModule, FormsModule, RouterModule ],
    declarations: [ LocalizationListComponent, LocalizationDetailsComponent ],
    providers: [ { provide: AbstractLocalizationService, useClass: MockLocalizationService } ]
})
export default class LocalizationModule {

}

localization.routes.ts

import { Routes, RouterModule } from "@angular/router";
import { LocalizationListComponent } from "../components/localization-list.component";
import { LocalizationDetailsComponent } from "../components/localization-details.component";

const routes: Routes = [
    {
        path: "",
        component: LocalizationListComponent,
        children: [
            {
                path: "localization",
                component: LocalizationListComponent
            },
            {
                path: ":id",
                component: LocalizationDetailsComponent
            },
            {
                path: "",
                component: LocalizationListComponent
            }
        ]
    }
];

export const localizationRoutes = RouterModule.forChild(routes);

localization-list.component.ts

import { Component, OnInit } from "@angular/core";
import { Localization } from '../models/localization';
import { Language } from "../models/language";

import { AbstractLocalizationService } from "../interfaces/AbstractLocalizationService";
import { AbstractLogger } from "../../logging/interfaces/AbstractLogger";
import { LoggerMessageType } from "../../logging/models/enums/LoggerMessageType";

@Component({
    moduleId: module.id,
    selector: "localization-list",
    templateUrl: "../views/localization-list.component.html"
})
export class LocalizationListComponent implements OnInit {
    localizations: Localization[];
    languages: Language[];

    constructor(private localizationService: AbstractLocalizationService,
            private logger: AbstractLogger) {

    }

    ngOnInit() : any {
        this.localizationService.getLocalizations()
            .subscribe((result: Localization[]) => {
                this.localizations = result;
                this.languages = this.localizations[0].languages;
            });
    }
}

app.component.html

<div class="container">
    <div class="page-header">
      <h1>VMS Localization<small>{{ status }}</small></h1>
      <app-navigation></app-navigation>
    </div>

    <router-outlet></router-outlet>
</div>

There must be something wrong with the above fragments (and the supplied project), but I cannot see any of it.

I also checked other questions on StackOverflow but they mostly deal with missing ROUTER_DIRECTIVES which I have in the app.component.ts

Thanks for your help people!

解决方案

I just came across an issue on GitHub (https://github.com/angular/angular/issues/10686) where it is explained that this is an intentional behavior. Every parent that has children (and it seems the same goes for loadChildren) must have it's own outlet in which to load the children.

It seems that this was not documented anywhere in the Router documentation.

UPDATE: When you declare children in a module's router, each parent must have it's own <router-outlet></router-outlet> in order to load this children. How to implement this depends on the needs. For my solution I created an empty component that just contains <router-outlet></router-outlet> and defined the route as following:

import { Routes, RouterModule } from "@angular/router"
import { SomeParentComponent } from "./app/modules/SomeModule/SomeParentComponent"
import { SomeChildComponent1 } from "./app/modules/SomeModule/SomeChild1Component"
import { SomeChildComponent2 } from "./app/modules/SomeModule/SomeChild2Component"

const routes: Routes = [
    path: "",
    component: SomeParentComponent,
    children: [
        {
            path: "",
            component: SomeChild1Component
        },
        {
            path: ":id",
            component: SomeChild2Component
        }
    ]
]

export const someModuleRoutes = RouterModule.forChild(routes);

This should do the trick as the main component route will call loadChildren pointing at SomeParentComponent.

这篇关于无法找到加载“LocalizationListComponent"的主要出口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆