获取 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);
你必须使用:
- ROUTER_BINDINGS 在你的 bootstrap.
- 在你的 index.html.
- 如果可能使用状态,即 "employees" 将 i.r 大写为 "Employees"。 (在 alpha 42 中我用这种方法解决了一个问题)。
希望对您有所帮助。
--更新--
alpha41 发布后:
ROUTER_BINDINGS
已更改为 ROUTER_PROVIDERS
。
- 路由器别名应采用驼峰式。
- 对于 Router-outler 和 router-link,您只需在组件注释的指令 属性 中导入
ROUTER_DIRECTIVES
。
Router-link
期望值是一个路由名称数组。获取更多信息。参考 here .
有关路由的更多信息,您可以参考本教程 here。
---更新2---
- 现在(从 alpha-49 开始)路由器导出为 ng.router。
(根据 alpha-47 所有生命周期钩子重命名为。)
onActivate、onReuse、onDeactivate、canReuse、canDeactivate
收件人:--
routerOnActivate、routerOnReuse、routerOnDeactivate、routerCanReuse、routerCanDeactivate
---更新3---
router-link
改为 routerLink
和routeconfig 属性改为:
{path: '/abc', component: ABC, as: 'abc'}
到:
{path: '/xyz' , component: XYZ, name: 'xyz'}
--更新4--
更新到 Angular2 RC
在 RC 之后,angular2 中的路由发生了很多变化,我在这里提到的一些要点可能会对某人有所帮助:-
angular2/router
已更改为 @angular/router
(您也可以使用导入 @angular/router-deprecated
的旧路由功能,但截至目前我们必须使用 @angular/router
)。
@RouteConfig
已更改为 @Routes
。
例如:-
@Routes([
{path: '/crisis-center', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent}
])
routerInjectables
已重命名为 ROUTER_BINDINGS
ROUTER_BINDINGS
已重命名为 ROUTER_PROVIDERS
使用ROUTER_PROVIDERS
ROUTER_PROVIDERS
用于简化引导路由器。
它包括:
RouterRegistry
- 注册路由集合
LocationStrategy = PathLocationStrategy
- 按路径匹配
ROUTER_PROVIDERS
提供 'sane' 默认值,应该使用,除非您需要不同的路由 LocationStrategy
.
变化:
bootstrap(DashboardAppComponent);
收件人:
bootstrap(DashboardAppComponent, [
ROUTER_PROVIDERS
]);
来源:
路由别名需要采用 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 混淆
来源:
- https://groups.google.com/d/msg/angular/IF3_UCJt340/6AgSF76XAwAJ
- angular/issues#4318
- angular/pr#4643
提示:
如果您想简化视图指令,请使用 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
{
}
我使用 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);
你必须使用:
- ROUTER_BINDINGS 在你的 bootstrap.
- 在你的 index.html.
- 如果可能使用状态,即 "employees" 将 i.r 大写为 "Employees"。 (在 alpha 42 中我用这种方法解决了一个问题)。
希望对您有所帮助。
--更新--
alpha41 发布后:
ROUTER_BINDINGS
已更改为ROUTER_PROVIDERS
。- 路由器别名应采用驼峰式。
- 对于 Router-outler 和 router-link,您只需在组件注释的指令 属性 中导入
ROUTER_DIRECTIVES
。 Router-link
期望值是一个路由名称数组。获取更多信息。参考 here .
有关路由的更多信息,您可以参考本教程 here。
---更新2---
- 现在(从 alpha-49 开始)路由器导出为 ng.router。
(根据 alpha-47 所有生命周期钩子重命名为。)
onActivate、onReuse、onDeactivate、canReuse、canDeactivate
收件人:--
routerOnActivate、routerOnReuse、routerOnDeactivate、routerCanReuse、routerCanDeactivate
---更新3---
router-link
改为routerLink
和routeconfig 属性改为:
{path: '/abc', component: ABC, as: 'abc'}
到:{path: '/xyz' , component: XYZ, name: 'xyz'}
--更新4--
更新到 Angular2 RC
在 RC 之后,angular2 中的路由发生了很多变化,我在这里提到的一些要点可能会对某人有所帮助:-
angular2/router
已更改为@angular/router
(您也可以使用导入@angular/router-deprecated
的旧路由功能,但截至目前我们必须使用@angular/router
)。@RouteConfig
已更改为@Routes
。
例如:-
@Routes([
{path: '/crisis-center', component: CrisisListComponent},
{path: '/heroes', component: HeroListComponent}
])
routerInjectables
已重命名为ROUTER_BINDINGS
ROUTER_BINDINGS
已重命名为ROUTER_PROVIDERS
使用ROUTER_PROVIDERS
ROUTER_PROVIDERS
用于简化引导路由器。
它包括:
RouterRegistry
- 注册路由集合LocationStrategy = PathLocationStrategy
- 按路径匹配
ROUTER_PROVIDERS
提供 'sane' 默认值,应该使用,除非您需要不同的路由 LocationStrategy
.
变化:
bootstrap(DashboardAppComponent);
收件人:
bootstrap(DashboardAppComponent, [
ROUTER_PROVIDERS
]);
来源:
路由别名需要采用 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 混淆
来源:
- https://groups.google.com/d/msg/angular/IF3_UCJt340/6AgSF76XAwAJ
- angular/issues#4318
- angular/pr#4643
提示:
如果您想简化视图指令,请使用 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
{
}