2016-08-24 245 views
0

我正在構建一個應用程序,您可以隨時在兩種語言之間進行更改。我有一個模擬服務,爲我提供了我使用的短語。當用戶點擊語言鏈接時,模擬服務中的語言會發生變化,但當我收到短語時,我需要以某種方式聆聽這些更改,因此服務會以我想要的語言向我返回更新後的短語。收聽Angular 2中模擬服務的變化

LangService.ts:

activeLang :string = 'EN'; 
getPhrase(phrase :string) :string{ 
    if(this.activeLang == 'EN'){ 
     return this.EN[phrase]; 
    } else { 
     return this.CZ[phrase]; 
    } 
    } 

    changeLanguage(lang :string) :void{ 
    if(lang == 'EN' || lang == 'CZ'){ 
     this.activeLang = lang; 
    } 
    } 

那麼一些OtherComponent.ts:

setPhrase(phrase :string){ 
    this._langService.getPhrase(phrase); 
    // Here I need to subscribe to getPhrase to get the latest updates 
    // If I'm right and if it's possible 
    } 

UPDATE

我做了一些修正。 LangService現在擁有我們可以偵聽的Observable,但偵聽器只能用於觸發方法changeLanguage()的組件。我希望能夠從NavigationComponent中更改語言並捕獲某些OtherComponent中的更改。

LangService.ts:

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class LangService { 
private activeLang = 'EN'; 
private activeLangSubject = new Subject<string>(); 
activeLang$ = this.activeLangSubject.asObservable(); 

// Objects EN and CZ with properties, etc. 

getPhrases(phrases :Array<string>){ 
    if(this.activeLang == 'EN'){ 
    let response = <any>{}; 
    for(let i = 0; i < phrases.length; i++){ 
     response[phrases[i]] = this.EN[phrases[i]]; 
    } 
    console.log('refresh'); 
    return JSON.stringify(response); 
    } else { 
    let response = <any>{}; 
    for(let i = 0; i < phrases.length; i++){ 
     response[phrases[i]] = this.CZ[phrases[i]]; 
    } 
    return JSON.stringify(response); 
    } 
} 

changeLanguage(lang :string){ 
    if(lang == 'EN' || lang == 'CZ'){ 
    this.activeLang = lang; 
    this.activeLangSubject.next(lang); 
    } 
} 

NavComponent.ts:

import { Component, OnInit } from '@angular/core'; 
import { LangService } from '../lang.service'; 

@Component({ 
    moduleId: module.id, 
    selector: 'app-nav', 
    templateUrl: 'nav.component.html', 
    styleUrls: ['nav.component.css'], 
    providers: [LangService] 
}) 
export class NavComponent implements OnInit { 
    langs :Array<string> = ['EN', 'CZ']; 

    constructor(
    private _langService :LangService) { 
    } 

    changeLanguage(lang :string) :void{ 
    this._langService.changeLanguage(lang); 
    } 
} 

與NavComponent.html:

<li *ngFor="let lang of langs"> 
    <a (click)="changeLanguage(lang)">{{ lang }}</a> 
</li> 

OtherComponent.ts:

import { Component, OnInit } from '@angular/core'; 
import { LangService } from '../lang.service'; 
import { NavComponent } from '../nav/nav.component'; 

@Component({ 
    moduleId: module.id, 
    selector: 'all-notes', 
    templateUrl: 'notes.component.html', 
    providers: [NoteService, LangService], 
    directives: [NavComponent] 
}) 
export class NotesComponent implements OnInit { 

    mode = 'Observable'; 

    postPhrases :Array<string> = [ 
    "alertTitle", "alertText", "options", "detailsBtn","editBtn","deleteBtn", 
    "addBtn", "serverResp", "actionMessage", "responseMessage", "note" 
    ]; 

    getPhrases :Object; 

    constructor(
    private _langService :LangService) { 
    } 

    ngOnInit() { 
    this.updatePhrases(this.postPhrases); 

    // This one doesn't work 
    this._langService.activeLang$.subscribe(
     success => this.updatePhrases(this.postPhrases), 
     error => console.log(error), 
    () => console.log('complete') 
    ); 
    } 

    updatePhrases(phrases :Array<string>) :void { 
    this.getPhrases = JSON.parse(this._langService.getPhrases(phrases)); 
    } 

} 

我現在的問題是如何偵聽OtherComponent上的更改,以便我可以使用updatePhrases()方法更新短語。

回答

0

所以基本上我需要的是用3個變量創建一個服務LangService。

activeLang: string 'EN'; 
activeLangSubject: Subject<string> = new Subject<string>(); 
activeLangObservable: Observable<string> = this.activeLangSubject.asObservable(); 
  1. activeLang - 用於比較的語言變量,
  2. activeLangSubject - 創建一個可觀察的變量,
  3. activeLangSubject - 變量,我們可以訂閱

在那之後,我需要將LangService添加到正確的範圍。我希望這是全球性的,所以我把它作爲引導方法的提供者在main.ts文件中。

bootstrap(AppComponent, [LangService]); 

當然我需要提供它來引導之前將其導入。

在引導提供它畢竟我需要做的是:

  • 其導入需要聽的變化每一個組件,
  • 不要在那裏將它作爲我們的全球instace它和我們不希望創建其他
  • 注入它的構造constructor(private _langService: LangService) {}
  • 訂閱它

    ngOnInit() { this._langService.langServiceObservable.subscribe( response => console.log('Changed! Active Language: ' + response), error => console.log('Error! Description: ' + error) ); }

如果你不使用ngOnInit(),您也可以訂閱內部構造)的變化(

1

這聽起來象是你可以使用一個管道爲:

import { Pipe, PipeTransform, Injectable } from '@angular/core' 

@Injectable() 
@Pipe({ name: 'myTranslatePipe' }) 
export class IndicatorHeadersPipe implements PipeTransform { 
    public transform(
    phrase: string, 
    activeLang: string 
) { 
    if(activeLang == 'EN'){ 
     return this.EN[phrase]; 
    } else { 
     return this.CZ[phrase]; 
    } 
    } 
} 

不要忘了管道添加到您的NgModule聲明

,然後在你的組件

@Component({ 
    selector: 'my-selector', 
    template: ` 
    <div>{{ 'My text' | myTranslatePipe : activeLang }}</div> 
    `, 
}) 
export class PageIndicatorComponent { 
    private activeLang: string 

    changeLanguage(lang :string) :void{ 
    if(lang == 'EN' || lang == 'CZ'){ 
     this.activeLang = lang; 
    } 
    } 
} 

但是,我會建議只使用翻譯模塊,如ng2-translate