Ant*_*ton 4 angularjs angular-translate angular-upgrade angular
我正在将AngularJS(即Angular 1.6)应用程序升级到Angular(即Angular 4.1.3).我选择进行增量升级,因此目前AngularJS和Angular都是自举和运行的.到目前为止这么好,但是:应该重写为Angular的AngularJS服务之一依赖于众所周知的服务$translate,该服务是第三方AngularJS(读取Angular 1)模块pascalprecht.translate的一部分.换句话说,$translate注入服务MyService应该成为Angular(读取Angular 4)服务.
MyService (剥离)看起来像这样:
import { Injectable } from '@angular/core';
@Injectable()
export class MyService {
// Here comes the injection (how to do it?).
constructor(private $translate: $translate) {
}
foo() {
// Use the service
this.$translate('HELLO_WORLD');
}
}
Run Code Online (Sandbox Code Playgroud)
它位于MyModule:
import { NgModule } from '@angular/core';
import { MyService } from './my.service';
@NgModule({
providers: [
MyService
]
})
export class MyModule {
}
Run Code Online (Sandbox Code Playgroud)
现在,我怎么能注入$translate到MyService时MyService驻留在角模块,而内部$translate是一个第三方AngularJS模块的一部分?
我知道如果AngularJS服务位于同一个模块中(或者至少模块是我自己的解决方案的一部分),如何将AngularJS服务注入Angular服务.官方文档中对此进行了解释.有没有办法处理第三方服务?我是否需要在MyModule提供商内注册该服务?
import { NgModule } from '@angular/core';
import { MyService } from './my.service';
// How this line should look line then?
import { $translate } from 'node_modules/angular-translate/...';
@NgModule({
providers: [
MyService,
$translate
]
})
export class MyModule {
}
Run Code Online (Sandbox Code Playgroud)
还是我想要实现不可能?
好吧,经过几个小时的挣扎,我终于找到了解决方案.这里是:
首先,遵循Angular的官方指南并升级第三方服务的提供商 - $translate.像这样:
AJS升级,providers.ts
import { InjectionToken } from '@angular/core';
import { downgradeInjectable } from '@angular/upgrade/static';
import 'angular-translate';
// Variable 'i' holds the standard AngularJS injector
export function $translateFactory(i: any) {
return i.get('$translate');
};
// There is no class representing the good old $translate service so we have
// a non-class dependency. Therefore we use an InjectionToken (Angular 4) or
// OpaqueToken (Angular 2).
export let $translate = new InjectionToken('$translate');
// Finally create the upgraded provider
export const $translateProvider = {
provide: $translate,
useFactory: $translateFactory,
deps: ['$injector']
};
Run Code Online (Sandbox Code Playgroud)
有一点需要注意,$translate服务可能依赖于其他旧的AngularJS服务,例如(在我的情况下)$translateStaticFilesLoader或$translateMessageFormatInterpolation.如果这也是您的情况,请务必扩展上面的代码并为这些服务创建升级的提供程序(将它们保存在同一个文件中).
import语句有效它angular-translate是作为节点模块安装的语句
import 'angular-translate';
Run Code Online (Sandbox Code Playgroud)
如果您tsconfig.json已设置使用,则工作正常moduleResolution: "node".
然后,当然,您需要确保该import语句即使在将代码从TypeScript转换为ES5(或您使用的任何目标)并由模块加载器(在我的情况下为SystemJS)中获取之后也能正常工作.
请注意,我们导入angular-translate脚本时没有从中获取任何内容,只是为了引起副作用.基本上,导入确保$translate简单地执行包含所需服务的脚本并$translate为AngularJS $注入器注册服务.
现在确保新升级的$translate服务提供商在其他提供商中注册MyModule.
my.module.ts
import { NgModule } from '@angular/core';
import { MyService } from './my.service';
import { $translateProvider } from './ajs-upgraded-providers';
@NgModule({
providers: [
MyService,
$translateProvider
]
})
export class MyModule {
}
Run Code Online (Sandbox Code Playgroud)
最后,使用该$translate服务MyService.
my.service.ts
import { Injectable, Inject } from '@angular/core';
import { $translate } from './ajs-upgraded-providers';
@Injectable()
export class MyService {
// Notice the usage of InjectionToken
constructor(@Inject($translate) private $translate: any) {
}
foo() {
this.$translate('hello.world').then((translation: string) => {
console.log(translation);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
602 次 |
| 最近记录: |