无法在 router-outlet child 中找到提供商

Cant find provider in router-outlet child

我已经构建了一个服务来处理我的 http 请求 ApiService 并且我添加了几个文件来很好地包装我的 http 调用以便我可以处理它们(仅举一个,它们都是遵循相同的样式 EmailApiService 等,并根据需要将数据传回我的组件。

我遇到的问题是,在我使用路由器控制的组件之一 ReportsComponent 中,出现错误

angular2.js?1460130081845:23877 EXCEPTION: Error: Uncaught (in promise): No provider for EmailApiService! (ReportsComponent -> EmailApiService)

EmailApiService 方法的调用在 ReportsComponent

的构造函数中

当我将相同的调用添加到我的 ToolbarComponent 构造函数时(与我为报告所做的相同)它们工作得很好。

这让我相信要么是将提供程序传递给通过路由器添加的 children 的方式出了问题,要么是我处理方法不正确。

app.component

import {ToolbarComponent} from './toolbar.component';
//pages
import {HomeComponent} from '../../home/components/home.component';
import {ReportsComponent} from '../..//reports/components/reports.component';
import {SignInComponent} from '../../signin/components/signin.component';
import {UserDetailsService} from '../../shared/services/user-details.service';
import {ApiService} from '../../shared/services/api.service';
import {EmailApiService} from '../../shared/services/email-api.service';
@Component({
  selector: 'app',
  viewProviders: [ApiService, EmailApiService, UserDetailsService],
  directives: [ROUTER_DIRECTIVES, ToolbarComponent]
})
@RouteConfig([
  { path: '/', name: 'Sign In', component: SignInComponent, useAsDefault: true },
  { path: '/home', name: 'Home', component: HomeComponent },
  { path: '/reports', name: 'Reports', component: ReportsComponent }
])

export class AppComponent {
  constructor() {}
}

app.html(调用在 <toolbar> 而不是 <router-outlet>(当我通过导航栏导航到报告页面时)

<div class="container-fluid">
  <toolbar></toolbar>      
  <router-outlet></router-outlet>
</div>

api服务

@Injectable()
export class ApiService {
  constructor(public http: Http,
              public userDetailService: UserDetailsService) {
  }

  request(type: RequestMethod, url: string, data: any, afterSuccess?: any) {
    ....
  }

  get(url: string, data: any, afterSuccess?: any) {
    ....
  }

  post(url: string, data: any, afterSuccess?: any) {
    ....
  }
}

emailapiService

@Injectable()
export class EmailApiService {

  token: string;
  service_provider_id: number;

  constructor(public apiService: ApiService,
              public userDetailService: UserDetailsService) {
    this.token = this.userDetailService.token;
    this.service_provider_id = this.apiService.service_provider_id;
  }

  emailExists() {
....
    return this.apiService.get('emails/email-address/exists');
  }


  emailSend()
....
    return this.apiService.post('emails/send');
  }
}

reportsComponent(不起作用,抛出缺少提供者)

@Component({
  selector: 'reports',
  moduleId: module.id,
  templateUrl: './reports.component.html',
  styleUrls: ['./reports.component.css'],
  directives: []
})
export class ReportsComponent {
  constructor (public emailApiService: EmailApiService,
               public userDetailsService: UserDetailsService) {
    this.emailApiService.emailExists('test@gmail.com');
    this.emailApiService.emailSend('test', 'test@gmail.com');
    console.log(this.userDetailsService.loggedIn);
  }
}

toolbarComponent(有效,调用成功)

@Component({
  selector: 'toolbar',
  moduleId: module.id,
  templateUrl: './toolbar.component.html',
  styleUrls: ['./toolbar.component.css'],
  directives: []
})
export class ToolbarComponent {
  constructor(public emailApiService: EmailApiService,
    public userDetailsService: UserDetailsService) {
    this.emailApiService.emailExists('test@gmail.com');
    this.emailApiService.emailSend('test', 'test@gmail.com');
    console.log(this.userDetailsService.loggedIn);
  }
}

我看过并阅读过的一件事是将 apiService 和 emailApiService 以及 UserDetailService 添加到我的 bootstrap,但我觉得我不需要这样做,而且我可能错过了一些东西它在工具栏上有效。

我的 bootstrap 来自我的 main.ts

bootstrap(AppComponent, [
  ROUTER_PROVIDERS,
  HTTP_PROVIDERS,
  provide(APP_BASE_HREF, { useValue: '<%= APP_BASE %>' })
]);

在此先感谢您花时间帮助我。

编辑

我已经尝试将应用程序组件中的 viewProviders 更改为 providers,但我仍然遇到同样的问题。

我觉得通过 bootstrap 提供的方式实际添加这些文件可能是正确的,因为它们将是可以在整个应用程序中访问并用于存储和共享数据的文件。

<div class="container-fluid>
                           ^ missing closing "
  <toolbar></toolbar>      
  <router-outlet></router-outlet>
</div>

否则无法重现Plunker example

编辑 在评论中找到并讨论了解决方案。 在导入中有一个额外的 /

import {ReportsComponent} from '../..//reports/components/reports.component';`

应该是

import {ReportsComponent} from '../../reports/components/reports.component';`