Getting Angular2 error 'No provider for Router

2020-02-04 07:04发布

问题:

I use Angular2 alpha39 and Babel to transpile the ES6 JS file. I'm not using typescript.

I created a component which displays correctly. I added a router-outlet to the template. When I run the app, I get the error message:

No provider for Router! (RouterOutlet -> Router)

The call stack is:

Here is the snippet of code:

template:

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

Component file:

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:

you have to use:

  1. ROUTER_BINDINGS in your bootstrap.
  2. in your index.html.
  3. if possible use state i.e as "employees" in capitalize i.r as "Employees". (in alpha 42 i have solve one problem this way).

i hope this will surely help you.

--UPDATE--

after the relese of alpha41:

  1. ROUTER_BINDINGS has been changed with ROUTER_PROVIDERS .
  2. Router Aliases should be in the camel case manner.
  3. for the Router-outler and router-link you just have to import ROUTER_DIRECTIVES in your directives property in the component annotation.
  4. Router-link expects the value to be an array of route names. for more info. refer here .

for more info regarding Routing you may refer to this tutorial here .

---Update2---

  1. Now ( as of alpha-49) router is exported as ng.router.
  2. (According to alpha-47 all life cycle hooks renamed as.)

    onActivate, onReuse, onDeactivate, canReuse, canDeactivate

    To :--

    routerOnActivate,routerOnReuse,routerOnDeactivate,routerCanReuse,routerCanDeactivate

---Update3---

  1. router-link is changed to routerLink

  2. and routeconfig property changed to:

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

--Update 4 --

UPDATE TO ANGULAR2 RC

There are alot of changes has been made in routing in angular2 after RC some of them points i am going to mention here may help someone :-

  1. angular2/router has been changed with @angular/router (also you can use old functionality of routing using import of @angular/router-deprecated but as of now we have to use @angular/router).

  2. @RouteConfig has been changed with @Routes .

for example :-

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


回答2:

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

  • routerInjectables was renamed to ROUTER_BINDINGS

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

  • ROUTER_BINDINGS was renamed to ROUTER_PROVIDERS

USE ROUTER_PROVIDERS

ROUTER_PROVIDERS is used to simplify bootstrapping the router.

It includes:

  • RouterRegistry - the collection of registered routes
  • LocationStrategy = PathLocationStrategy - match by path

ROUTER_PROVIDERS provides 'sane' defaults and should be used unless you need to need a different route LocationStrategy.

Change:

bootstrap(DashboardAppComponent);

To:

bootstrap(DashboardAppComponent, [
  ROUTER_PROVIDERS
]);

Sources:

  • angular/commit/ccfadb9
  • angular/pr#4654

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

Route aliases need to be CamelCase (technically PascalCase)

Note: this was mentioned already in Pardeep's answer under #3

If you want to include a link to a route in your template via router-link you have to make sure the alias (ie the name property) of the route is PascalCase.

If you use plan to use router-link modify the route to:

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

Then you can add the link in your template with:

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

RouterLink dynamically inserts a href that matches the route path.

Note: Reading the issue/pr it appears this change was made to prevent users from confusing the <route-link> binding with the route url

Sources:

  • https://groups.google.com/d/msg/angular/IF3_UCJt340/6AgSF76XAwAJ
  • angular/issues#4318
  • angular/pr#4643

Tip:

If you want to simplify your view directives use ROUTER_DIRECTIVES

It includes:

  • RouterLink
  • RouterOutlet

Update:

In the near future, RouterOutlet/<router-outlet> will be renamed to RouterViewport/<router-viewport>

Source:

  • angular/issues#4679

Update 2:

  • The RouteConfig property as has been renamed to name

Source:

  • angular/commit/7d83959


回答3:

Answer on Dec 23rd 2016 (Angular v2.4.1, Router v3.4.1 - should work for any NG v2.x.x + Router v3.x.x)

I just migrated three of our apps from the Webpack Starter Seed to Angular CLI (v1.0.0-beta.24) and hit this issue.

Only a tiny fraction of what's on the NG 2 massive router doc page is required:

An app-routing.module.ts file (typically in src/app/ folder) looking like this sample:

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 {}

Import AppRoutingModule into your main module (typically 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 { }

Ensure you have <router-outlet></router-outlet> somewhere in your main html (often src/app/app.component.html) as this is where router content is injected.



回答4:

Make sure you have router defined and declared in AppModule. Example (look everywhere where routing is mentioned, ignore the rest):

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);

and 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 {
}


回答5:

This can save someone an hour:

You get this error if you don't even use routing (for example temporary, maybe you don't import routing config and router-outlet is commented out) BUT you are using Router or ActivatedRoute in some component constructor via dependency injection, like this:

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


回答6:

You cant user Dependency Injection for Router if you dont define any routs! To define route user something similar to following codes:

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
{
}