2017-09-15 66 views
4

我開發一個應用程序角度,我期待在Android開發提供類似到Android資源的東西。字符串資源的角度

這裏是得到一個字符串中的Android方式:

String mystring = getResources().getString(R.string.mystring);

我想有角一樣。

例如,如果我有,其中有大約提供了錯誤的電子郵件相同的消息幾個HTML模板...

<div class="alert alert-danger"> 
     <strong>Error!</strong>Invalid e-mail 
</div> 

我想有以下幾點:

<div class="alert alert-danger"> 
     <strong>Error!</strong>{{myStrings.INVALID_EMAIL}} 
</div> 

。 ..或類似的東西...

<div class="alert alert-danger"> 
     <strong>Error!</strong>{{'INVALID_EMAIL' | stringGenerator}} 
</div> 

你知道一種方式或插件,我可以安裝以達到?從應用程序的邏輯分離

+0

使用'NGX-translate' –

回答

6

具有配置,翻譯和資源是非常有用的。在其他情況下,配置也會非常有用,例如,獲取api_url對於任何其他呼叫都很有用。

可以使用@angular/cli建立這樣的事情。具有以下應用程序結構:

|- app 
|- assets 
     |- i18n 
       - en.json 
       - it.json 
     |- json-config 
       - development.json 
       - env.json 
       - production.json 
     |- resources 
       - en.json 
       - it.json 
|- environment 
     - environment.prod.ts 
     - environment.ts 

|- config 
     - app.config.ts  

其中:

  • 應用:包含所有應用程序邏輯
  • 資產/國際化/ * JSON:包含可用於文本資源在你的任何組件中。對於我們想要涵蓋的每種語言,都有其中之一。

E.G. en.json

{ 
    "TEST": { 
    "WELCOME" : "Welcome" 
} 

E.G it.json

{ 
    "TEST": { 
    "WELCOME" : "Benvenuto" 
} 
  • 資產/ JSON-配置:包括配置文件在開發模式和生產模式來使用。還包含env.json這是一個json,它說當前的開發模式是:

E.G. env.json

{ 
    "env" : "development" 
} 

E.G.development.json

{ 
    "API_URL" : "someurl", 
    "MYTOKEN" : "sometoken", 
    "DEBUGGING" : true 
} 
  • 資產/資源:包含每個我們要覆蓋每個語言資源jsons文件。例如,它可能包含應用程序模型的jsons初始化。例如,如果您想填充模型陣列以便根據環境和/或語言進行個性化設置,那麼這很有用。這種初始化應該在每個想要通過AppConfig.getResourceByKey訪問精確資源的組件內部完成,這些將在稍後顯示。

  • app.config.ts:Configuration Service根據開發模式加載資源的服務。我會在下面顯示一個片段。

基本配置

爲了在應用程序啓動,我們需要做一些事情來加載基本配置文件。

app.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core'; 
/** App Services **/ 
import { AppConfig } from '../config/app.config'; 
import { TranslationConfigModule } from './shared/modules/translation.config.module'; 

// Calling load to get configuration + translation 
export function initResources(config: AppConfig, translate: TranslationConfigModule) { 
     return() => config.load(translate); 
} 

// Initializing Resources and Translation as soon as possible 
@NgModule({ 
    . . . 
    imports: [ 
     . . . 
     TranslationConfigModule 
    ], 
    providers: [ 
     AppConfig, { 
      provide: APP_INITIALIZER, 
      useFactory: initResources, 
      deps: [AppConfig, TranslationConfigModule], 
      multi: true 
     } 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { } 

app.config.ts

正如上面所說的,基於發展模式,在這種情況下,該服務加載配置文件,瀏覽器語言。如果要定製應用程序,則根據語言加載資源可能非常有用。例如,您的意大利發行版可能會有不同的路線,不同的行爲或簡單的不同文本。

每個資源配置與環境條目是可用的低谷AppConfig服務的方法,如getEnvByKeygetEntryByKeygetResourceByKey

import { Inject, Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { get } from 'lodash'; 
import 'rxjs/add/operator/catch'; 

import { TranslationConfigModule } from '../app/shared/modules/translation.config.module'; 

@Injectable() 
export class AppConfig { 

    private _configurations: any = new Object(); 
    private _config_path = './assets/json-config/'; 
    private _resources_path = './assets/resources/'; 

    constructor(private http: Http) { } 

    // Get an Environment Entry by Key 
    public getEnvByKey(key: any): any { 
    return this._configurations.env[key]; 
    } 

    // Get a Configuration Entryby Key 
    public getEntryByKey(key: any): any { 
    return this._configurations.config[key]; 
    } 

    // Get a Resource Entry by Key 
    public getResourceByKey(key: any): any { 
    return get(this._configurations.resource, key); 
    } 

    // Should be self-explanatory 
    public load(translate: TranslationConfigModule){ 
    return new Promise((resolve, reject) => { 
     // Given env.json 
     this.loadFile(this._config_path + 'env.json').then((envData: any) => { 
     this._configurations.env = envData; 
     // Load production or development configuration file based on before 
     this.loadFile(this._config_path + envData.env + '.json').then((conf: any) => { 
      this._configurations.config = conf; 
      // Load resources files based on browser language 
      this.loadFile(this._resources_path + translate.getBrowserLang() +'.json').then((resource: any) => { 
      this._configurations.resource = resource; 
      return resolve(true); 
      }); 
     }); 
     }); 
    }); 
    } 

    private loadFile(path: string){ 
    return new Promise((resolve, reject) => { 
     this.http.get(path) 
     .map(res => res.json()) 
     .catch((error: any) => { 
      console.error(error); 
      return Observable.throw(error.json().error || 'Server error'); 
     }) 
     .subscribe((res_data) => { 
      return resolve(res_data); 
     }) 
    }); 
    } 

} 

translation.config.module.ts

此模塊設置使用ngx-translate內置的翻譯。根據瀏覽器語言設置翻譯。

import { HttpModule, Http } from '@angular/http'; 
import { NgModule, ModuleWithProviders } from '@angular/core'; 
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core'; 
import { TranslateHttpLoader } from '@ngx-translate/http-loader'; 
import { isNull, isUndefined } from 'lodash'; 


export function HttpLoaderFactory(http: Http) { 
    return new TranslateHttpLoader(http, '../../../assets/i18n/', '.json'); 
} 

const translationOptions = { 
    loader: { 
     provide: TranslateLoader, 
     useFactory: HttpLoaderFactory, 
     deps: [Http] 
    } 
}; 

@NgModule({ 
    imports: [TranslateModule.forRoot(translationOptions)], 
    exports: [TranslateModule], 
    providers: [TranslateService] 
}) 
export class TranslationConfigModule { 

    private browserLang; 

    /** 
    * @param translate {TranslateService} 
    */ 
    constructor(private translate: TranslateService) { 
     // Setting up Translations 
     translate.addLangs(['en', 'it']); 
     translate.setDefaultLang('en'); 
     this.browserLang = translate.getBrowserLang(); 
     translate.use(this.browserLang.match(/en|it/) ? this.browserLang : 'en'); 
    } 

    public getBrowserLang(){ 
     if(isUndefined(this.browserLang) || isNull(this.browserLang)){ 
      this.browserLang = 'en'; 
     } 
     return this.browserLang; 
    } 
} 

好了,現在?我怎樣才能使用這種配置?

任一模塊/組件導入app.module.ts或任何他們被導入到被導入translation.config.module現在可以自動轉換基於瀏覽器的語言任何插值進入另一個自定義模塊。例如使用以下剪斷,將產生基於解釋的行爲,歡迎韋努託

{{ 'TEST.WELCOME' | translate }} 

如果我想獲得的資源來初始化一定的陣列將被傳遞到*ngFor

在任何組件,只是做的構造函數中:

. . . 

// Just some model 
public navigationLinks: NavigationLinkModel[]; 

constructor(private _config: AppConfig) { 
    // PAGES.HOMEPAGE.SIDENAV.NAVIGATION contains such model data 
    this.navigationLinks = 
    this._config.getResourceByKey('PAGES.HOMEPAGE.SIDENAV.NAVIGATION'); 
} 

當然你也可以聯合的資源和配置。

+1

您好安德烈,感謝您的回答!你的回答給了我有關創建服務,有專門的方法來獲得字符串,它加載本地JSON的可能性,一個有趣的想法。但隨後邀請我將它與NGX-翻譯相結合。在這一點上我semplificherei創建服務,並讓他做這一切,否則我就在NGX-翻譯完全信任。它是一個或其他的,不是嗎? – smartmouse

+0

你好聰明,就像你說的,你也可以只依賴'NGX-translate'但我想強調的另一點。在包含的資產中的第二類型的JSON把基於所述配置和/或語言,如果你想在要使用NGX-轉換爲定製文本輸入的組件初始化數組可以是有用的,例如被加載。例如,你有一個導航欄,你要重複這個鏈接以'ngFor',每個環節都有了'title',這取決於語言的變化。此時初始化入口'resources'與NGX-translate'和''title'。 – AndreaM16

+0

原諒我,我不明白你的意思是初始化'resources'項內容。其實我有一個導航欄,但最終他們管理與'NGX-translate'串 – smartmouse