Angular2事件Emmiter订阅vs公共变量?

时间:2016-08-18 20:25:41

标签: events angular internationalization

我正在为我的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
    }
}

0 个答案:

没有答案