Angular 2 throwing error: Outlet is not activated

Angular 2 throwing error: Outlet is not activated

我已经设置了我的应用程序,这样我就有了一个 Recipe Book,其中有一个 Recipies 的列表,当我点击一个食谱时,它会在一个嵌套的列表中显示 Recipe Details路线。这还有一个按钮,单击该按钮可在 Recipes Details 内的嵌套路径中加载成分。

到目前为止路由似乎工作正常,除非我尝试导航到另一个 Recipe。如果 Ingredients 托盘(路线)处于活动状态,那么它将更改食谱并折叠 Ingredients 路线,如果我随后尝试导航(不打开成分),我会收到以下错误:

Uncaught (in promise): Error: Outlet is not activated
Error: Outlet is not activated

看来我的路由器需要 Ingredients 才能激活,否则它无法理解嵌套路由。这就是我的看法,但不确定如何修复它或何时出错。

单食谱-page.component.html

<app-tray class="recipe-list">
    <app-recipe-list [recipe]="recipe"></app-recipe-list>
</app-tray>
<router-outlet></router-outlet>

食谱-detail.component.html

<app-tray class="recipe">
    The routing has worked and loaded recipe.
</app-tray>
<router-outlet></router-outlet>

成分-list.component.html

<app-tray class="ingredients-list">
    Recipe Ingredients have loaded.
</app-tray>

app.routes.ts(更新)

export const routerConfig : Route[] = [
  {
    path: 'recipe-books',
    children: [
      {
        path: ':id', component: SingleRecipeBookPageComponent,
        children: [
          {
            path: 'recipes',
            children: [
              { path: ':id', component: RecipeDetailComponent,
                children: [
                  { path: '', component: IngredientsListComponent },
                  { path: 'ingredients', component: IngredientsListComponent }
                ]
              },
              { path: 'new', component: IngredientsListComponent },
              { path: '', component: RecipeDetailComponent }
            ]
          },
          { path: '', redirectTo: 'recipes', pathMatch: 'full' }
        ]
      },
      { path: '', component: RecipeBooksPageComponent }
    ]
  },
  { path: 'ingredients', component: IngredientsComponent },
  { path: '', redirectTo: 'recipe-books', pathMatch: 'full' },
  { path: '**', redirectTo: 'recipe-books', pathMatch: 'full' }
];

此路由无效,您应该收到错误消息。

{ path: '' },

路由需要有 componentredirectTochildren

如果一个空路径路由没有 children 它也应该有 pathMatch: 'full'.

我猜你想要的是

{ path: '', component: DummyComponent, pathMatch: 'full' },

其中 DummyComponent 是具有空视图的组件。 您可以为所有这些路径重复使用相同的 DummyComponent

这可能会对其他人有所帮助。

我遇到了这个错误。我已经检查了我的路由文件中所有定义的 routespathcomponents 定义正确。

出现此错误的原因是我忘记在 app.module.ts 中添加对 service 的引用,该引用在我的组件之一中用于从 RestApi 获取数据。

因此,始终在创建服务后立即在 providers 部分的 app.module.ts 中添加服务引用。

imports: [
   BrowserModule,
   HttpModule,
   ......
 ],

providers: [
    AuthService, 
    ........ // Here, service reference
]

TLDR;答案:

{
      path: ':question',
      runGuardsAndResolvers: GUARDS_RESOLVERS_DISABLED   // blocks component creation
}

其中 GUARDS_RESOLVERS_DISABLED 是全局函数(以避免 AOT 问题)。

 export function GUARDS_RESOLVERS_DISABLED() { return false; }

Angular 路由器中有一个 new feature 听起来与此问题相关,但据我所知,这不是它的直接解决方案。新选项是 runGuardsAndResolvers = 'pathParamsChange',它会影响 Angular 检查守卫和解析器的时间 - 并且至关重要的是它是否运行此出口检查。

所以在我找到新选项之前:

  • 我正在进入 angular 代码 - 实际错误发生在此处(以红色突出显示)在 context.outlet.component(其中 component 是一个 getter投掷)。

  • 所以要修复我只需要以某种方式制作 shouldRun == false

  • shouldRun 只是 shouldRunGuardsAndResolvers(...) 所以如果可以将其设置为 return false 那么它就不会尝试在 'wrong'地方。

所以解决方法很简单:

 {
        path: 'contactus',
        component: ContactUsComponent,

        children: [
            {
                path: 'topics',
                pathMatch: 'full'
            },
            
            {
                path: 'faq',
                component: FaqPanelComponent
            },
            
            { 
                path: 'test',
                component: ContactusTopicListComponent
            },
            {
                path: ':category',
                
                children: 
                [
                    {
                        path: ':question',
                        runGuardsAndResolvers: () => false   // blocks component creation
                    }
                ]
            }
        ]
    },

目前 runGuardsAndResolvers 有相当多的 few options,但我使用的总是 returns false 等同于 never真的应该成为一种选择。但这就是我发现新路由器功能的方式:-)

此外,如果您有两个级别,则需要将其放在两个级别(或可能只是最高级别):

        {
            path: ':category',
            runGuardsAndResolvers: () => false,
            
            children: 
            [
                {
                    path: ':question',
                    runGuardsAndResolvers: () => false
                }
            ]
        }

进一步阅读解析器:https://blog.angularindepth.com/new-in-angular-v7-1-updates-to-the-router-fd67d526ad05


编辑: 要使其与 AOT / Angular 9/10+ 一起正常工作,您可以创建一个全局函数来避免 Sunil 提到的问题。

export function GUARDS_RESOLVERS_DISABLED() { return false; }

然后使用这个语法

runGuardsAndResolvers: GUARDS_RESOLVERS_DISABLED

对于生产 runGuardsAndResolvers: () => 不工作。 Angular 具有 runGuardsAndResolvers 的新功能。

为了工作,你可以尝试 runGuardsAndResolvers: "pathParamsChange" 在 Angular 中测试 8 工作正常。