我正在为我的Angular 2应用程序做一个i18n服务系统。 为了避免不纯的管道,我向翻译管道添加了一个额外的参数,该更改将触发管道值更新,因此它将更新翻译的文本。
最佳做法是什么:从服务中提升事件并在每个组件中订阅以检测语言更改
VS
将服务变量lang
设置为公开,并将其作为参数添加到管道中?
我已经过测试,但两者都有效。
使用事件发射器:
component.html
<button md-button class="btn-register">{{'Register' | _:lang}}</button>
component.ts
export class LoginComponent implements OnInit {
loginForm: FormGroup;
public lang: string;
onLangChange: EventEmitter<LangChangeEvent>;
constructor(private _fb: FormBuilder, private _authService: AuthService, private tr:TranslateService) {
}
ngOnInit():any {
//monitor language change
this.onLangChange = this.tr.onLangChange.subscribe( (event: LangChangeEvent) => {
this.lang = event.lang;
});
this.loginForm = this._fb.group({
email: ['', Validators.required],
password: ['', Validators.compose( [Validators.required, hasNumbers] ) ]
});
}
onSubmit(form) {
this._authService.login( this.loginForm.value );
}
}
translate.service.ts
import {Injectable, EventEmitter} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import {Languages} from "../config/Constants";
export interface LangChangeEvent {
lang: string;
}
@Injectable()
export class TranslateService {
public lang: string;
dictionary: any = {};
/**
* An EventEmitter to listen to lang change events
* onLangChange.subscribe((params: LangChangeEvent) => {
* // do something
* });
* @type {ng.EventEmitter<LangChangeEvent>}
*/
public onLangChange: EventEmitter<LangChangeEvent> = new EventEmitter<LangChangeEvent>();
constructor(private http: Http, private path:string) {
let lang = this.detectLang();
this.setLanguage(lang);
}
/**
* A standard alias used for the translate function
* @param val
* @returns {string}
* @private
*/
public _(val: string) {
return this.dictionary[val] ? this.dictionary[val] : val;
}
public setLanguage(lang: string) {
if(Languages[lang]) {
this.loadLanguage(lang, Languages[lang].path);
}
}
private loadLanguage(lang:string, url: string) {
return this.http.get(url).toPromise()
.then( dictionary =>
{
this.dictionary = dictionary.json();
this.lang = lang;
this.onLangChange.emit({ lang: this.lang });
})
.catch( error => console.log(error) );
}
private detectLang(): string {
if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
return 'en';
}
let browserLang: any;
if (typeof window.navigator['languages'] !== 'undefined' && window.navigator['languages'].length > 0) {
browserLang = window.navigator['languages'][0].indexOf('-') !== -1 || window.navigator['languages'].length < 2 ? window.navigator['languages'][0] : window.navigator['languages'][1];
} else {
browserLang = window.navigator['language'] || window.navigator['browserLanguage'];
}
return browserLang && browserLang.length ? browserLang.split('-')[0] : 'en'; // use navigator lang if available
}
}
使用公共变量:
<button md-button class="btn-register">{{'Register' | _:tr.lang}}</button>
component.ts
export class LoginComponent implements OnInit {
loginForm: FormGroup;
constructor(private _fb: FormBuilder, private _authService: AuthService, private tr:TranslateService) {
}
ngOnInit():any {
this.loginForm = this._fb.group({
email: ['', Validators.required],
password: ['', Validators.compose( [Validators.required, hasNumbers] ) ]
});
}
onSubmit(form) {
this._authService.login( this.loginForm.value );
}
}
translate.service.ts
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/toPromise';
import {Languages} from "../config/Constants";
export interface LangChangeEvent {
lang: string;
}
@Injectable()
export class TranslateService {
public lang: string;
dictionary: any = {};
constructor(private http: Http, private path:string) {
let lang = this.detectLang();
this.setLanguage(lang);
}
/**
* A standard alias used for the translate function
* @param val
* @returns {string}
* @private
*/
public _(val: string) {
return this.dictionary[val] ? this.dictionary[val] : val;
}
public setLanguage(lang: string) {
if(Languages[lang]) {
this.loadLanguage(lang, Languages[lang].path);
}
}
private loadLanguage(lang:string, url: string) {
return this.http.get(url).toPromise()
.then( dictionary =>
{
this.dictionary = dictionary.json();
this.lang = lang;
})
.catch( error => console.log(error) );
}
private detectLang(): string {
if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
return 'en';
}
let browserLang: any;
if (typeof window.navigator['languages'] !== 'undefined' && window.navigator['languages'].length > 0) {
browserLang = window.navigator['languages'][0].indexOf('-') !== -1 || window.navigator['languages'].length < 2 ? window.navigator['languages'][0] : window.navigator['languages'][1];
} else {
browserLang = window.navigator['language'] || window.navigator['browserLanguage'];
}
return browserLang && browserLang.length ? browserLang.split('-')[0] : 'en'; // use navigator lang if available
}
}