获取 Angular2 错误 'No provider for Router! (RouterOutlet -> Router)'

Getting Angular2 error 'No provider for Router! (RouterOutlet -> Router)'

我使用 Angular2 alpha39 和 Babel 来转译 ES6 JS 文件。我没有使用打字稿。

我创建了一个可以正确显示的组件。我在模板中添加了一个 router-outlet。当我 运行 应用程序时,我收到错误消息:

没有路由器提供商! (RouterOutlet -> 路由器)

调用堆栈为:

这是代码片段:

模板:

.... // Removed for brevity
<div class="contenttext">
    <router-outlet></router-outlet>
</div>
.... // Removed for brevity

组件文件:

import { Component, View, bootstrap,  OnInit } from 'angular2/angular2';
import { RouteConfig, RouterOutlet, RouterLink } from 'angular2/router';
import 'reflect-metadata';
import 'winjs';

@Component({
    selector: 'dashboard-app'
})
@View({
    templateUrl: '../js/dashboard.html',
    directives: [ ContentComponent, FamiliesComponent, RouterOutlet, RouterLink ]
})
@RouteConfig([ 
    { path: '/employees', component: EmployeesComponent, as: 'employees'} 
]) 
class DashboardAppComponent implements OnInit {
    constructor() {
    }

    onInit() {
        WinJS.UI.processAll().done(function() {
            var splitView = document.querySelector(".splitView").winControl;
            new WinJS.UI._WinKeyboard(splitView.paneElement);
        })
    }
}

bootstrap(DashboardAppComponent);

你必须使用:

  1. ROUTER_BINDINGS 在你的 bootstrap.
  2. 在你的 index.html.
  3. 如果可能使用状态,即 "employees" 将 i.r 大写为 "Employees"。 (在 alpha 42 中我用这种方法解决了一个问题)。

希望对您有所帮助。

--更新--

alpha41 发布后:

  1. ROUTER_BINDINGS 已更改为 ROUTER_PROVIDERS
  2. 路由器别名应采用驼峰式。
  3. 对于 Router-outler 和 router-link,您只需在组件注释的指令 属性 中导入 ROUTER_DIRECTIVES
  4. Router-link 期望值是一个路由名称数组。获取更多信息。参考 here .

有关路由的更多信息,您可以参考本教程 here

---更新2---

  1. 现在(从 alpha-49 开始)路由器导出为 ng.router。
  2. (根据 alpha-47 所有生命周期钩子重命名为。)

    onActivate、onReuse、onDeactivate、canReuse、canDeactivate

    收件人:--

    routerOnActivate、routerOnReuse、routerOnDeactivate、routerCanReuse、routerCanDeactivate

---更新3---

  1. router-link 改为 routerLink

  2. 和routeconfig 属性改为:

    {path: '/abc', component: ABC, as: 'abc'} 到: {path: '/xyz' , component: XYZ, name: 'xyz'}

--更新4--

更新到 Angular2 RC

在 RC 之后,angular2 中的路由发生了很多变化,我在这里提到的一些要点可能会对某人有所帮助:-

  1. angular2/router 已更改为 @angular/router (您也可以使用导入 @angular/router-deprecated 的旧路由功能,但截至目前我们必须使用 @angular/router)。

  2. @RouteConfig 已更改为 @Routes

例如:-

@Routes([
  {path: '/crisis-center', component: CrisisListComponent},
  {path: '/heroes',        component: HeroListComponent}
])

2.0.0-alpha.36 (2015-08-31)

  • routerInjectables 已重命名为 ROUTER_BINDINGS

2.0.0-alpha.41 (2015-10-13)

  • ROUTER_BINDINGS 已重命名为 ROUTER_PROVIDERS

使用ROUTER_PROVIDERS

ROUTER_PROVIDERS 用于简化引导路由器。

它包括:

  • RouterRegistry - 注册路由集合
  • LocationStrategy = PathLocationStrategy - 按路径匹配

ROUTER_PROVIDERS 提供 'sane' 默认值,应该使用,除非您需要不同的路由 LocationStrategy.

变化:

bootstrap(DashboardAppComponent);

收件人:

bootstrap(DashboardAppComponent, [
  ROUTER_PROVIDERS
]);

来源:


2.0.0-alpha.38 (2015-10-03)

路由别名需要采用 CamelCase(技术上是 PascalCase)

注意:Pardeep 在#3

下的回答中已经提到了这一点

如果您想通过 router-link 将 link 添加到模板中的路由,您必须确保别名(即 name 属性)路线是 PascalCase.

如果使用计划使用router-link修改路由为:

{ path: '/employees', component: EmployeesComponent, name: 'Employees'}

然后您可以在模板中添加 link:

<a [router-link]="['/Employees']">Employees Link</a>

RouterLink 动态插入与路由路径匹配的 href。

注意:阅读 issue/pr 似乎进行此更改是为了防止用户将 <route-link> 绑定与路由 url 混淆

来源:

提示:

如果您想简化视图指令,请使用 ROUTER_DIRECTIVES

它包括:

  • RouterLink
  • RouterOutlet

更新:

在不久的将来,RouterOutlet/<router-outlet>将更名为RouterViewport/<router-viewport>

来源:

更新二:

  • RouteConfig 属性 as 已重命名为 name

来源:

确保您在 AppModule 中定义并声明了路由器。 例子(到处找路由,其他忽略):

app.routing.ts

import { ModuleWithProviders }  from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { HeroesComponent }      from './heroes.component';
import {DashboardComponent} from './dashboard.component';
import {HeroDetailComponent} from './hero-detail.component';

const appRoutes: Routes = [
  {
    path: 'heroes',
    component: HeroesComponent
  },
  {
  path: 'dashboard',
  component: DashboardComponent
},
{
  path: '',
  redirectTo: '/dashboard',
  pathMatch: 'full'
},
{
  path: 'detail/:id',
  component: HeroDetailComponent
},
];

export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);

和app.module.ts:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule }   from '@angular/forms';
import { HttpModule }    from '@angular/http';

// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';


import { AppComponent }         from './app.component';
import { DashboardComponent }   from './dashboard.component';
import { HeroesComponent }      from './heroes.component';
import { HeroDetailComponent }  from './hero-detail.component';
import { HeroService }          from './hero.service';
import { routing }              from './app.routing';
import './rxjs-extensions';
import {HeroSearchComponent} from './hero-search.component';

@NgModule({
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,

    routing
  ],
  declarations: [
    AppComponent,
    DashboardComponent,
    HeroDetailComponent,
    HeroesComponent,
    HeroSearchComponent
  ],
  providers: [
    HeroService,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {
}

回答于 2016 年 12 月 23 日(Angular v2.4.1,路由器 v3.4.1 - 应该适用于任何 NG v2.x.x + 路由器 v3.x.x)

我刚刚将我们的三个应用程序从 Webpack Starter Seed 迁移到 Angular CLI (v1.0.0-beta.24) 并遇到了这个问题。

只需要 NG 2 massive router doc page 上的一小部分:

一个应用程序-routing.module.ts 文件(通常在 src/app/ 文件夹中)看起来像这个示例:

import { NgModule }              from '@angular/core';
import { RouterModule, Routes }  from '@angular/router';

const appRoutes: Routes = [
  { path: '', component: YourHomePageComponent },
  { path: 'next-page',   component: NextComponent }
];

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

将 AppRoutingModule 导入您的主模块(通常是 src/app/app.module.ts):

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule  // <--- The import you need to add
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

确保你在主 html 的某处有 <router-outlet></router-outlet>(通常是 src/app/app.component.html)因为这是注入路由器内容。

这可以为某人节省一个小时:

如果您甚至不使用路由(例如临时的,也许您不导入路由配置并且 router-outlet 被注释掉)但您在某些组件中使用 Router 或 ActivatedRoute,则会出现此错误通过依赖注入构造函数,像这样:

@Component({...}})
export class SomeComponent {
constructor(private _router: Router, private _route: ActivatedRoute) {
//may be you are not using _route/_route at the moment at all!
}
...
}

如果您不定义任何路由,则无法为 Router 使用依赖注入! 要定义路由用户类似于以下代码:

const loginRoutes: Routes = [
    {path: 'foo/bar/baz', component: 'MyRootComponent'}
];

@NgModule({
    imports:      [
        BrowserModule,
        FormsModule,
        HttpModule,
        JsonpModule,
        RouterModule.forRoot(loginRoutes)
    ],
    providers:    [],
    declarations: [
        MyLoginComponent
    ],
    bootstrap:    [
        MyLoginComponent
    ]
})

export class MyLoginModule
{
}