2016-08-24 97 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