Angular 2:在构造函数

时间:2017-06-19 10:17:44

标签: angular typescript dependency-injection angular2-services ngx-translate

我想在定义路由以重定向到正确的语言而不是静态语言之前设置一个名为bootLang的变量。 我创建了一个服务,用于计算并返回本地存储中的语言(如果已设置)或浏览器语言。为此,我需要来自ngx-translate模块的TranslateService。

计算琅bootstrap.service.ts

import {Injectable} from '@angular/core';
import {TranslateService} from "@ngx-translate/core";

@Injectable()
export class ComputeLangBootstrapService {

  lang_computed: string|null;

  constructor(private translate: TranslateService){}

  getLang(): string {
    this.lang_computed = localStorage.getItem('lang-selected');
    if(!this.lang_computed){
      let browserLang = this.translate.getBrowserLang();
      this.lang_computed = browserLang.match(/en|es|it/) ? browserLang : 'en'
    }
    return this.lang_computed;
  }

}

我需要在定义路由之前实例化此服务,以便计算我必须在重定向路由定义中放置的语言。

应用-routing.module.ts

import { FooHomeComponent } from "./shore-home/shore-home.component";
import { FooDetailsComponent } from "./tour-details/tour-details.component";
import { ComputeLangBootstrapService } from "./services/compute-lang-bootstrap.service";



let injector = ReflectiveInjector.resolveAndCreate([ComputeLangBootstrapService]);
let bootLang = injector.get(ComputeLangBootstrapService).getLang();

const appRoutes: Routes = [
  { path: ':lang/tour-details/:id', component: FooDetailsComponent },
  { path: ':lang', component: FooHomeComponent },
  { path: '', redirectTo: bootLang, pathMatch: 'full' }
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes),
    CommonModule
  ],
  exports: [
    RouterModule
  ],
  declarations: []
})

export class AppRoutingModule {}

为此,我尝试使用我在AppModule中指定的工厂。

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule, Http } from '@angular/http';
import { TranslateModule, TranslateLoader, TranslateService} from '@ngx-translate/core';
import { TranslateHttpLoader } from "@ngx-translate/http-loader";

import { AppComponent } from './app.component';
import { FooHomeComponent } from './shore-home/shore-home.component';
import { AppRoutingModule } from "./app-routing.module";
import { FooDetailsComponent } from './tour-details/tour-details.component';
import { ComputeLangBootstrapService } from "./services/compute-lang-bootstrap.service";

// AoT requires an exported function for factories
export function HttpLoaderFactory(http: Http) {
  return new TranslateHttpLoader(http);
}

export function CLBFactory(translate: TranslateService) {
  return new ComputeLangBootstrapService(translate);
}

@NgModule({
  declarations: [
    AppComponent,
    FooHomeComponent,     
    FooDetailsComponent
  ],
  imports: [
    AppRoutingModule,
    HttpModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [Http]
      }
    })
  ],
  providers: [
    {
      provide: ComputeLangBootstrapService,
      useFactory: CLBFactory,
      deps: [TranslateService]
    }
  ],
  bootstrap: [AppComponent]
})

export class AppModule {}

通过这种方式,我收到了这个错误。

Uncaught Error: No provider for TranslateService! (ComputeLangBootstrapService -> TranslateService)

事实上,TranslateService可以像服务一样使用,但它不是用@injectable()装饰器声明的。 我尝试了很多其他的解决方法来实现我的目标,比如在ComputeLangBootstrapService中使用注入器来在构造函数外部实例化TranslateService或者创建一个Guard但是它没有在重定向路由中检查,因为重定向发生在Guard的检查之前。 有人知道达到目标的最佳做法是什么?

0 个答案:

没有答案