Skip to content

Commit e0ac54e

Browse files
committed
Merge branch 'issue48' of https://github.com/ribizli/ng2-translate into ribizli-issue48
2 parents f01ee79 + bcf664d commit e0ac54e

7 files changed

+139
-192
lines changed

README.md

+21-32
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,30 @@ System.config({
2121
```
2222

2323
Finally, you can use ng2-translate in your Angular 2 project (make sure that you've loaded the angular2/http bundle as well).
24-
It is recommended to instantiate `TranslateService` in the bootstrap of your application and to never add it to the "providers" property of your components, this way you will keep it as a singleton.
25-
If you add it to the "providers" property of a component it will instantiate a new instance of the service that won't be initialized.
24+
It is recommended to use `NG_TRANSLATE_PROVIDERS` in the bootstrap of your application and to never add `TranslateService` to the "providers" property of your components, this way you will keep it as a singleton.
25+
`NG_TRANSLATE_PROVIDERS` provides a default configuration for the static translation file loader.
26+
If you add `TranslateService` to the "providers" property of a component it will instantiate a new instance of the service that won't be initialized with the language to use or the default language.
2627

2728
```js
2829
import {HTTP_PROVIDERS} from 'angular2/http';
2930
import {Component, Injectable, provide} from 'angular2/core';
30-
import {TranslateService, TranslatePipe, TranslateLoader, TranslateStaticLoader} from 'ng2-translate/ng2-translate';
31+
import {NG_TRANSLATE_PROVIDERS, TranslateService, TranslatePipe,
32+
TranslateLoader, TranslateStaticLoader} from 'ng2-translate/ng2-translate';
3133
import {bootstrap} from 'angular2/platform/browser';
3234

3335
bootstrap(AppComponent, [
3436
HTTP_PROVIDERS,
3537
// not required if you use TranslateStaticLoader (default)
3638
// use this if you want to use another loader
37-
provide(TranslateLoader, {useClass: TranslateStaticLoader}),
38-
// not required, but recommended to have 1 unique instance of your service
39-
TranslateService
39+
// or to configure TranslateStaticLoader
40+
provide(TranslateLoader, {
41+
useFactory: (http: Http) => new TranslateStaticLoader(http),
42+
deps: [Http]
43+
}),
44+
// recommended to have 1 unique instance of your service
45+
NG_TRANSLATE_PROVIDERS
4046
]);
4147

42-
@Injectable()
4348
@Component({
4449
selector: 'app',
4550
template: `
@@ -63,11 +68,12 @@ export class AppComponent {
6368
}
6469
```
6570

66-
For now, only the static loader is available. You can configure it like this:
71+
For now, only the static loader is available. You can configure it like this during bootstrap:
6772
```js
68-
var prefix = 'assets/i18n';
69-
var suffix = '.json';
70-
translate.useStaticFilesLoader(prefix, suffix);
73+
provide(TranslateLoader, {
74+
useFactory: (http: Http) => new TranslateStaticLoader(http, 'assets/i18n', '.json'),
75+
deps: [Http]
76+
})
7177
```
7278

7379
Then put your translations in a json file that looks like this (for `en.json`):
@@ -79,7 +85,7 @@ Then put your translations in a json file that looks like this (for `en.json`):
7985

8086
An then you can get new translations like this:
8187
```js
82-
translate.getTranslation(userLang);
88+
translate.getTranslation(userLang);
8389
```
8490

8591
But you can also define your translations manually instead of using `getTranslation`:
@@ -104,14 +110,10 @@ translate.setTranslation('en', {
104110
```
105111

106112
#### Methods:
107-
- `useStaticFilesLoader()`: Use a static files loader
108-
- `useLoader(loader: TranslateLoader)`: Use a different loader
109113
- `setDefaultLang(lang: string)`: Sets the default language to use as a fallback
110114
- `use(lang: string): Observable<any>`: Changes the lang currently used
111115
- `getTranslation(lang: string): Observable<any>`: Gets an object of translations for a given language with the current loader
112116
- `setTranslation(lang: string, translations: Object)`: Manually sets an object of translations for a given language
113-
- `setMissingTranslationHandler(handler: MissingTranslationHandler): void`: sets the Missing Translation Handler which will be
114-
used when the requested translation is not available
115117
- `getLangs()`: Returns an array of currently available langs
116118
- `get(key: string|Array<string>, interpolateParams?: Object): Observable<string|Object>`: Gets the translated value of a key (or an array of keys)
117119
- `instant(key: string|Array<string>, interpolateParams?: Object): string|Object`: Gets the instant translated value of a key (or an array of keys)
@@ -139,17 +141,8 @@ bootstrap(AppComponent, [
139141
]);
140142
```
141143

142-
Or you can just use the `useLoader` method:
143-
```js
144-
export class AppComponent {
145-
constructor(translate: TranslateService, myLoader: CustomLoader) {
146-
translate.useLoader(myLoader);
147-
}
148-
}
149-
```
150-
151144
#### How to handle missing translations
152-
You can use the method `setMissingTranslationHandler` to define a handler that will be called when the requested translation is not available.
145+
You can setup a provider for `MissingTranslationHandler` to define a handler that will be called when the requested translation is not available.
153146
The only required method is `handle` where you can do whatever you want. Just don't forget that it will be called synchronously from the `get` & `instant` methods.
154147

155148
##### Example:
@@ -164,13 +157,9 @@ export class MyMissingTranslationHandler implements MissingTranslationHandler {
164157
}
165158
```
166159

167-
Set the Missing Translation Handler
160+
Setup the Missing Translation Handler in bootstrap
168161
```js
169-
constructor(translate: TranslateService) {
170-
...
171-
translate.setMissingTranslationHandler(new MyMissingTranslationHandler());
172-
...
173-
}
162+
provide(MissingTranslationHandler, { useClass: MyMissingTranslationHandler })
174163
```
175164

176165
### TranslatePipe

karma.conf.js

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module.exports = function(config) {
2727
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false, served: true },
2828
{ pattern: 'node_modules/systemjs/dist/system-polyfills.js', included: false, watched: false, served: true }, // PhantomJS2 (and possibly others) might require it
2929

30+
{ pattern: 'ng2-translate.ts', included: false, watched: true }, // source files
3031
{ pattern: 'src/**/*.ts', included: false, watched: true }, // source files
3132
{ pattern: 'tests/**/*.ts', included: false, watched: true }, // test files
3233
'karma-test-shim.js'

ng2-translate.ts

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1+
import {provide} from 'angular2/core';
2+
import {Http} from 'angular2/http';
13
import {TranslatePipe} from './src/translate.pipe';
2-
import {TranslateService} from './src/translate.service';
4+
import {TranslateService, TranslateLoader, TranslateStaticLoader} from './src/translate.service';
35

46
export * from './src/translate.pipe';
57
export * from './src/translate.service';
68
export * from './src/translate.parser';
79

8-
export default {
9-
pipes: [TranslatePipe],
10-
providers: [TranslateService]
11-
}
10+
export const NG_TRANSLATE_PROVIDERS: any = [
11+
provide(TranslateLoader, {
12+
useFactory: (http: Http) => new TranslateStaticLoader(http),
13+
deps: [Http]
14+
}),
15+
TranslateService
16+
];

src/translate.service.ts

+5-54
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,13 @@ export abstract class MissingTranslationHandler {
1111
abstract handle(key: string): void;
1212
}
1313

14-
@Injectable()
1514
export abstract class TranslateLoader {
1615
abstract getTranslation(lang: string): Observable<any>;
1716
}
1817

19-
@Injectable()
2018
export class TranslateStaticLoader implements TranslateLoader {
21-
private http: Http;
22-
private sfLoaderParams = {prefix: 'i18n', suffix: '.json'};
2319

24-
constructor(http: Http, @Optional() prefix: string, @Optional() suffix: string) {
25-
this.http = http;
26-
this.configure(prefix, suffix);
27-
}
28-
29-
/**
30-
* Defines the prefix & suffix used for getTranslation
31-
* @param prefix
32-
* @param suffix
33-
*/
34-
public configure(prefix: string, suffix: string) {
35-
this.sfLoaderParams.prefix = prefix ? prefix : this.sfLoaderParams.prefix;
36-
this.sfLoaderParams.suffix = suffix ? suffix : this.sfLoaderParams.suffix;
20+
constructor(private http: Http, private prefix: string = 'i18n', private suffix: string = '.json') {
3721
}
3822

3923
/**
@@ -42,7 +26,7 @@ export class TranslateStaticLoader implements TranslateLoader {
4226
* @returns {any}
4327
*/
4428
public getTranslation(lang: string): Observable<any> {
45-
return this.http.get(`${this.sfLoaderParams.prefix}/${lang}${this.sfLoaderParams.suffix}`)
29+
return this.http.get(`${this.prefix}/${lang}${this.suffix}`)
4630
.map((res: Response) => res.json());
4731
}
4832
}
@@ -54,11 +38,6 @@ export class TranslateService {
5438
*/
5539
public currentLang: string = this.defaultLang;
5640

57-
/**
58-
* An instance of the loader currently used
59-
*/
60-
public currentLoader: TranslateLoader;
61-
6241
/**
6342
* An EventEmitter to listen to lang changes events
6443
* onLangChange.subscribe((params: {lang: string, translations: any}) => {
@@ -74,33 +53,9 @@ export class TranslateService {
7453
private langs: Array<string>;
7554
private parser: Parser = new Parser();
7655

77-
/**
78-
* Handler for missing translations
79-
*/
80-
private missingTranslationHandler: MissingTranslationHandler;
81-
82-
constructor(private http: Http, @Optional() loader: TranslateLoader) {
83-
if(loader !== null) {
84-
this.currentLoader = loader;
85-
} else {
86-
this.useStaticFilesLoader();
87-
}
88-
}
89-
90-
/**
91-
* Use a translations loader
92-
* @param loader
93-
*/
94-
public useLoader(loader: TranslateLoader) {
95-
this.currentLoader = loader;
96-
}
97-
98-
/**
99-
* Use a static files loader
100-
*/
101-
public useStaticFilesLoader(prefix?: string, suffix?: string) {
102-
this.currentLoader = new TranslateStaticLoader(this.http, prefix, suffix);
103-
}
56+
constructor(private http: Http,
57+
public currentLoader: TranslateLoader,
58+
@Optional() private missingTranslationHandler: MissingTranslationHandler) {}
10459

10560
/**
10661
* Sets the default language to use as a fallback
@@ -265,8 +220,4 @@ export class TranslateService {
265220
this.onLangChange.emit({lang: lang, translations: this.translations[lang]});
266221
}
267222

268-
public setMissingTranslationHandler(handler: MissingTranslationHandler) {
269-
this.missingTranslationHandler = handler;
270-
}
271-
272223
}

tests/translate.pipe.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {TranslatePipe} from '../src/translate.pipe';
22
import {MockConnection, MockBackend} from "angular2/src/http/backends/mock_backend";
3-
import {TranslateService} from "../src/translate.service";
3+
import {NG_TRANSLATE_PROVIDERS, TranslateService} from "./../ng2-translate";
44
import {XHRBackend, HTTP_PROVIDERS} from "angular2/http";
55
import {provide, Injector} from "angular2/core";
66

@@ -17,7 +17,7 @@ export function main() {
1717
HTTP_PROVIDERS,
1818
// Provide a mocked (fake) backend for Http
1919
provide(XHRBackend, {useClass: MockBackend}),
20-
TranslateService,
20+
NG_TRANSLATE_PROVIDERS,
2121
TranslatePipe
2222
]);
2323
backend = injector.get(XHRBackend);

0 commit comments

Comments
 (0)