рдХреЛрдгреАрдп: ngx- рдЕрдиреБрд╡рд╛рджред рд╡реЗрдмрдкреИрдХ рдХреЗ рд╕рд╛рде рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдореЗрдВ рд╕реБрдзрд╛рд░

рд╢реБрдн рджрд┐рдиред


рдпрд╣ рдПрдирдЬреАрдПрдХреНрд╕-рдЯреНрд░рд╛рдВрд╕рд▓реЗрд╢рди рд▓рд╛рдЗрдл рд╣реИрдХреНрд╕ рдХрд╛ рд╕рдордп рд╣реИред рдкреНрд░рд╛рд░рдВрдн рдореЗрдВ, рдореИрдВрдиреЗ 3 рднрд╛рдЧреЛрдВ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рджреВрд╕рд░рд╛ рднрд╛рдЧ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдЬрд╛рдирдХрд╛рд░реАрдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИ - рдЗрд╕рдореЗрдВ рдореИрдВ 2 рднрд╛рдЧ рдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдпрдерд╛рд╕рдВрднрд╡ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛ред


рднрд╛рдЧ 1


TranslateHttpLoader рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП AppTranslateLoader рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рд╣рдорд╛рд░рд╛ AppTranslateLoader рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рд▓реИрдВрдЧреНрд╡реЗрдЬ рдкрд░ рдзреНрдпрд╛рди рджреЗрдЧрд╛ рдФрд░ рдЗрд╕рдореЗрдВ рдлрд╛рд▓рдмреИрдХ рд▓реЙрдЬрд┐рдХ, рдореЛрдореЗрдВрдЯрдЬ рд▓реЛрдХреЗрд╢рдиреНрд╕ рдЗрдореНрдкреЛрд░реНрдЯ рдХрд░реЗрдЧрд╛ рдФрд░ APP_INITIALIZER рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реЛрдб рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬреАрд╡рди рдХреЗ 2 рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЗ рд╕рдВрдпреЛрдЬрди рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╣рдо рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рд▓рдЪреАрд▓реЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХрд░реЗрдВрдЧреЗред


рдореБрдЦреНрдп рд▓рдХреНрд╖реНрдп AppTranslateLoader рдирд╣реАрдВ рд╣реИ (рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ рдФрд░ рдмрдирд╛рдиреЗ рдореЗрдВ рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ), рд▓реЗрдХрд┐рди рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХрд╛ рдирд┐рд░реНрдорд╛рдгред


рдореИрдВрдиреЗ рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕реБрд▓рдн рд▓рд┐рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВрдХрд┐ рд▓реЗрдЦ рдореЗрдВ рдмрд╣реБрдд рд╕реА рдЪреАрдЬреЗрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рд▓рдЧреЗрдЧрд╛ рдФрд░ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реЛрдЧрд╛ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ)ред рдЗрд╕рд▓рд┐рдП, рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд▓реЗрдЦ рдмрд╣реБрдд рдЕрдиреБрдХреВрд▓ рдирд╣реАрдВ рдерд╛ред рджреВрд╕рд░реА рдУрд░, рдЕрдВрдд рдореЗрдВ рдкреНрд░реЛрдбрдЧ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓рд┐рдВрдХ рд╣реИред


рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ http рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд▓реЛрдбрд░ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рд╕реНрддрд░ рдкрд░ рд╣рдорд╛рд░реЗ рдмрдВрдбрд▓ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рднрд╛рд╖рд╛рдУрдВ рдХреЛ рд▓реЛрдб рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЖрдкрдХреЛ http рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд▓реЛрдбрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рджреВрд╕рд░реА рдУрд░, рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде, рдЖрдкрдХреЛ рд╣рд░ рдмрд╛рд░ рдЬрдм рд╣рдо рдЕрдкрдиреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдмрджрд▓рддреЗ рд╣реИрдВ, рдФрд░ рд╕рд╛рде рд╣реА, рдпрд╣ .jpg рдмрдВрдбрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдмрд╣реБрдд рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВред


 // webpack-translate-loader.ts import { TranslateLoader } from '@ngx-translate/core'; import { Observable } from 'rxjs/Observable'; export class WebpackTranslateLoader implements TranslateLoader { getTranslation(lang: string): Observable<any> { return Observable.fromPromise(System.import(`../assets/i18n/${lang}.json`)); } } 

рдЕрдЧрд░ IDE System рдкрд░ рд╢рдкрде рд▓реЗрддрд╛ рд╣реИ System рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред


 declare var System: System; interface System { import(request: string): Promise<any>; } 

рдЕрдм рд╣рдо WebpackTranslateLoader рдореЗрдВ WebpackTranslateLoader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 @NgModule({ bootstrap: [AppComponent], imports: [ TranslateModule.forRoot({ loader: { provide: TranslateLoader, useClass: WebpackTranslateLoader } }) ] }) export class AppModule { } 

AppTranslateLoader


рддреЛ, рдЪрд▓реЛ рд╣рдорд╛рд░реЗ AppTranslateLoader рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред рдЗрд╕рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдХрдИ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬрд┐рдирдХрд╛ рдорд╛рдирдХ TranslHttpLoader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝реЗрдЧрд╛:


  • рдЕрдиреБрд╡рд╛рдж рдЯрд┐рдордЯрд┐рдорд╛рддреЗ рд╣реБрдПред TranslateHttpLoader рдХреЛ рдпрд╣ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╣рдо рдПрдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЖ рд╕рдХрддреЗ рд╣реИрдВ рдЬрдм рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЗ рдмрд╛рдж рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╕рд╣реА рд▓реЗрдмрд▓реНрд╕ рдХреЗ рд▓рд┐рдП рдЬрдЧрд╣ рд╣реИ - рдХреБрдВрдЬрд┐рдпрд╛рдБ (MY_BUTTON -KEY рдореЗрд░реЗ рдмрдЯрди рдХрд╛ рд╕реНрдерд╛рди рд╣реИ), рдЬреЛ рдПрдХ рдкрд▓ рдХреЗ рдмрд╛рдж рд╕рд╣реА рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреА рд╣реИрдВред


  • рддрд┐рдерд┐ред рдРрд╕реА рд╕реЗрд╡рд╛ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдЬреЛ рддрд┐рдерд┐рдпреЛрдВ рдХреЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЛ рдмрджрд▓ рджреЗред рдЬрдм рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдкрд╛рда рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рддрд┐рдерд┐рдпреЛрдВ, рд╕рдордп рдЖрджрд┐ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк AngJular рдореЗрдВ рдирд┐рд░реНрдорд┐рдд рдХреНрд╖рдгрдЬ рдпрд╛ i18n рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рджреЛрдиреЛрдВ рд╕рдорд╛рдзрд╛рди рдЕрдЪреНрдЫреЗ рд╣реИрдВ, рдФрд░ рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рд╕реНрд╡рд░реВрдкрдг рдХреЗ рд▓рд┐рдП рдХреЛрдгреАрдп 2+ рдкрд╛рдЗрдк рд╣реИрдВред


  • рднрдВрдбрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред TranslateHttpLoader рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЖрдкрдХреЛ рдЕрдкрдиреЗ json рдмрдВрдбрд▓реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХреИрд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ FE рд╕рд░реНрд╡рд░ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЕрдиреНрдпрдерд╛, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдг рджреЗрдЦреЗрдВрдЧреЗ, рдЗрд╕рд╕реЗ рднреА рдмрджрддрд░ рд╡реЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреБрдВрдЬреА рджреЗрдЦреЗрдВрдЧреЗ (рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдХреИрд╢рд┐рдВрдЧ рдХреЗ рдмрд╛рдж рдирдП рдЬреЛрдбрд╝реЗ рдЧрдП рдереЗ)ред рдореИрдВ рдХреИрд╢рд┐рдВрдЧ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдХреНрд╖рдг рдХреЗ рд╕рд╛рде рдПрдХ рдирдП рд╕рд░реНрд╡рд░ рдкрд░ рддреИрдирд╛рдд рд╣рд░ рдмрд╛рд░ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ред рдЗрд╕рд▓рд┐рдП рд╣рдо рд╡реЗрдмрдкреИрдХреНрд╕ рдХреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рдм рдХреБрдЫ рдХрд░ рджреЗрдВрдЧреЗ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рдпрд╣ .js рдмрдВрдбрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реИред

AppTranslateLoader рдбреНрд░рд╛рдлреНрдЯ


рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рдорд╛рдзрд╛рди:

1. рдЕрдиреБрд╡рд╛рдж рдЯрд┐рдордЯрд┐рдорд╛ рд╕рдорд╕реНрдпрд╛ - AppTranslateLoader рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ APP_INITIALIZER рдХрд╛ APP_INITIALIZER

APP_INITIALIZER рднреА рддрд╛рдЬрд╝рд╛ рдЯреЛрдХрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рд▓реЗрдЦ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рд╢рд╛рдорд┐рд▓ рдерд╛, рдпрджрд┐ рдЗрдирд┐рд╢рд▓рд╛рдЗрдЬрд╝рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ рдирд╣реАрдВ рд╣реИ - рдореИрдВ рдЖрдкрдХреЛ рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рд▓реЗрдЦ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рддрд╛рдЬрд╝рд╛ рдЯреЛрдХрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╢реБрд░реБрдЖрддреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ (рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдПрдХ рд╢реБрд░реБрдЖрддреА рд╣реИ), рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдРрд╕реЗ рд▓реЛрдЧ рд╣реИрдВ рдЬреЛ рдХрд╛рдо рдореЗрдВ рдЖрддреЗ рд╣реИрдВ:


 //app.module.ts export function translationLoader(loader: AppTranslateLoader) { return () => loader.loadTranslation(); } @NgModule({ bootstrap: [AppComponent], providers: [ { provide: APP_INITIALIZER, useFactory: translationLoader, deps: [AppTranslateLoader], multi: true } ] }) export class AppModule { } 

2. рдЦрдЬреВрд░ рдХреА рд╕рдорд╕реНрдпрд╛ред рд╣рдо рдмрд╕ рднрд╛рд╖рд╛ рдореЗрдВ рдкрд▓ рднрд░ рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВрдЧреЗред рд╕рд╛рде рдореЗрдВ ngx-tranlateред

рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ - рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рд╕рд╛рде json рд▓реЛрдб рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдмрд╕ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЛ рдХреНрд╖рдгреЛрдВ (рдпрд╛ i18n) рдкрд░ рд╕реНрд╡рд┐рдЪ рдХрд░рддреЗ рд╣реИрдВред


рдпрд╣ рднреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ i18n рдХреА рддрд░рд╣, рдХреНрд╖рдгрдЬ, рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЛ рдЕрд▓рдЧ рд╕реЗ рдЖрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдВрд╡реЗрдЧ рднреА рдПрдХ рдмрдВрдбрд▓ рдЖрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рдкреВрд░реЗ рдмрдВрдбрд▓ рдореЗрдВ ~ 260KB рд▓рдЧрддреЗ рд╣реИрдВ, рдФрд░ рдЖрдкрдХреЛ рдЙрдирдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ 2 рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред


рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдЖрдк рдЙрдирдореЗрдВ рд╕реЗ рдХреЗрд╡рд▓ 2 рдХреЛ рд╕реАрдзреЗ рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЖрдпрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд╣рд╛рдВ AppTranslateLoader рдШреЛрд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


 import 'moment/locale/en-gb'; import 'moment/locale/ru'; 

рдЕрдм en-gb рдФрд░ ru рд╕реНрдерд╛рдиреАрдпрдХрд░рдг js рдПрдкреНрд▓реАрдХреЗрд╢рди рдмрдВрдбрд▓ рдореЗрдВ рд╣реЛрдВрдЧреЗред AppTranslateLoader рдЖрдк рдПрдХ рддрд╛рдЬрд╝рд╛ рднрд░реА рд╣реБрдИ рднрд╛рд╖рд╛ рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:


 export Class AppTranslateLoader { // .... private onLangLoaded(newLang: string) { //     if (this.loadedLang && this.loadedLang !== newLang) { this.translate.resetLang(this.loadedLang); } this.loadedLang = newLang; this.selectedLang = newLang; // TODO:       //     ,       //  en  ru,  momentJs   en. moment().locale(newLang); //  .  momentJs localStorage.setItem(this.storageKey, newLang); //   ls this.loadSubj.complete(); //   -      . } 

!!! рдЗрд╕ рд╣реИрдВрдбрд▓рд░ рдореЗрдВ рдПрдХ рдЦрд╛рдореА рд╣реИ: рдЕрдЧрд░ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдирдЬреАрдПрдХреНрд╕-рдЯреНрд░рд╛рдВрд╕рд▓реЗрд╢рди рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдПрди рд▓реЛрдХрд▓рд╛рдЗрдЬреЗрд╢рди рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдпрд╛ рдПрди рдпрд╛ рдПрди-рдЬреАрдмреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рддреЛ рдкреНрд░реЛрд╕реЗрд╕рд░ рд▓реЙрдЬрд┐рдХ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдпрд╛ рдПрди-рдЬреАрдмреА рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рднреА рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред NGX-рдЕрдиреБрд╡рд╛рдж рдХрд░рддреЗ рд╣реИрдВред


!!! // TODO рдХреЗ рд╕рд╛рде рдлрд┐рд▓рд╣рд╛рд▓: рд╣рдо рдПрдХ рд╡реЗрдмрдкреИрдХ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдо рдмрд╛рдж рдореЗрдВ рдХреБрдЫ рдкреНрд▓рдЧрдЗрдиреНрд╕ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рдЕрднреА рддрдХ рдирд╣реАрдВ рд╣реИред


рдЖрдк рдкреВрдЫрддреЗ рд╣реИрдВ, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдореЗрдВ рдкрд╛рда рдХреЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рд╕рд╛рде-рд╕рд╛рде рджрд┐рдирд╛рдВрдХ рдФрд░ рд╕рдордп рдХреЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЛ рд▓реЛрдб рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рдХреНрдпреЛрдВ рд╣реИ (рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ, HTTP рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ)? рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рддрд┐рдерд┐ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдореЗрдВ рдЕрдкрдирд╛ рддрд░реНрдХ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдереЛрдбрд╝рд╛ 'рдЧрдВрджрд╛' рдХреЛрдб рд▓рд┐рдЦрдХрд░ рдРрд╕реЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рд╣реИред рдореИрдВ рдЙрддреНрдкрд╛рджрди рдореЗрдВ рдЗрд╕ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдмрдВрдбрд▓ рдХреЗ рдЕрдВрджрд░ 2 рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдореБрдЭреЗ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ рдХрдИ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рд╣реИрдВ, рддреЛ рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рд▓реЛрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдФрд░ рдмрд╣реБрдд рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдирд╣реАрдВ, рдзреНрдпрд╛рди рд░рдЦреЗрдВ:


 private async loadAngularCulture(locale) { let angularLocaleText = await this.httpClient.get(`assets/angular-locales/${locale}.js`).toPromise(); // extracting the part of the js code before the data, // and i didn't need the plural so i just replace plural by null. const startPos = angularLocaleText.indexOf('export default '); angularLocaleText = 'return ' + angularLocaleText.substring(startPos + 15).replace('plural', null); // The trick is here : to read cldr data, i use a function const f = new Function(angularLocaleText); const angularLocale = f(); // console.log(angularLocale); // And now, just registrer the object you just created with the function registerLocaleData(angularLocale); } 

рдкрд┐рдЫрд▓реА рдмрд╛рд░ рдореИрдВрдиреЗ рдПрдВрдЧреБрд▓рд░ 4 рдореЗрдВ рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдерд╛ред рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЕрднреА рдХрд╛рдо рдХрд░ рд░рд╣реА рд╣реИред


рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдЧрдВрджрд╛ рдЬреАрд╡рди рд╣реИрдХ рд╕реАрдЬреЗрдЬ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ (рдХреЗрд╡рд▓ рдХреЛрдгреАрдп рд╕реНрдерд╛рдиреАрдпрдХрд░рдг)ред рдХрдо рд╕реЗ рдХрдо рдореБрдЭреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рдорд┐рд▓рд╛, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдмрд╣реБрдд рджрд╛рдврд╝реА рд╡рд╛рд▓реЗ рд╣реИрдХрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рдорд╛рдзрд╛рди рджреЗрдЦрдХрд░ рдЦреБрд╢реА рд╣реЛрдЧреАред


3. рдХреИрд╢рд┐рдВрдЧред .Js рдмрдВрдбрд▓ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рдорд╛рди, рдЖрдк .json рдмрдВрдбрд▓ рдирд╛рдо рдореЗрдВ рдПрдХ рд╣реИрд╢ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рд╕рдм рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЖрдк рд╕рднреА json'es рдХреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреИрд╕реЗ рдПрдХрддреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рдмрд╕ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕рдм рдХреБрдЫ рд╣реЛред рдЗрдВрдЯрд░рдиреЗрдЯ рдореЗрдВ, рдЖрдк рдХрдИ рдПрдирдкреАрдПрдо рдореЙрдбреНрдпреВрд▓ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЫреЛрдЯреЗ рд╕реЗ рдЬрд╕рди рдПрдХрддреНрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдореБрдЭреЗ рд╡реЗ рдирд╣реАрдВ рдорд┐рд▓реЗ рдЬреЛ рдПрдХ рд╣реИрд╢ рд╕реЗ рдЬреБрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдлрд╛рдЗрд▓ рдореЗрдВ рд╕рдм рдХреБрдЫ рдПрдХрддреНрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдПрдирдПрдХреНрд╕рдПрдХреНрд╕-рдЯреНрд░рд╛рдВрд╕рд▓реЗрдЯ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рд╡реЗрдмрдкреИрдХ рдЦреБрдж рднреА рдЬрд╕рди рдХреЛ рд╕рдВрднрд╛рд▓ рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ рд╡реЗрдмрдкреИрдХ рдкреНрд▓рдЧрдЗрди рдХреЛ рд▓рд┐рдЦреЗрдВрдЧреЗред


рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ: рд╣рдореЗрдВ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рднреА рдЬреЛрдВрд╕ рдХреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрдЯрд░реНрди рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЗрдХрдЯреНрдард╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдирд╛рдо (en, ru, de, рдЖрджрд┐) рджреНрд╡рд╛рд░рд╛ рд╕рдореВрд╣рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, en.json рд╡рд┐рднрд┐рдиреНрди рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдлрд┐рд░, рдкреНрд░рддреНрдпреЗрдХ рдПрдХрддреНрд░рд┐рдд рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдПрдХ рд╣реИрд╢ рд╕рдВрд▓рдЧреНрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред


рдпрд╣рд╛рдВ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИред рдпрджрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХрд╛ рдЕрдкрдирд╛ рдирд╛рдо рд╣реИ, рддреЛ AppTranslateLoader рдлрд╝рд╛рдЗрд▓ рдирд╛рдореЛрдВ рдХреЛ рдХреИрд╕реЗ рдкрд╣рдЪрд╛рдирддрд╛ рд╣реИ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, index.html рдореЗрдВ рдмрдВрдбрд▓ рд╕рд╣рд┐рдд, рд╣рдо HtmlWebpackPlugin рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреЗ рдЖрдк рдмрдВрдбрд▓ рдХреЗ рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЯреИрдЧ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВред


.Json рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░рд╛ рд╡реЗрдмрдкреИрдХ рдкреНрд▓рдЧрдЗрди config.json рдмрдирд╛рдПрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рд╣реИрд╢ рдлрд╛рдЗрд▓ рдирд╛рдо рдХреЗ рд╕рд╛рде рднрд╛рд╖рд╛ рдХреЛрдб рдХрд╛ рдЬреБрдбрд╝рд╛рд╡ рд╣реЛрдЧрд╛:


 { "en": "en.some_hash.json", "ru": "ru.some_hash.json" } 

config.json рднреА рдмреНрд░рд╛рдЙрдЬрд╝рд░ рджреНрд╡рд╛рд░рд╛ рдХреИрд╢ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛ рд╕рдордп рд▓рдЧреЗрдЧрд╛ рдФрд░ рдЬрдм рд╣рдо рдЗрд╕ рдлрд╛рдЗрд▓ рдХреЛ рдУрд╡рд░рдЧреНрд░реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рддрдм рд▓рдЧрд╛рддрд╛рд░ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓реЛрдб рдХрд░ рд░рд╣реЗ рд╣реИрдВ) рдЬрдм рд╣рдо рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдХреНрд╡реЗрд░реАрд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдкреИрд░рд╛рдореАрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╛ config.json рдХреЛ рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЖрдИрдбреА рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ (рдореИрдВ рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдкрд╣рд▓рд╛ Google рдореЗрдВ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ)ред


рдореИрдВ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдБрдЪреЗ рдФрд░ рдкрд░рдорд╛рдгреБрддрд╛ рдХреЛ рдереЛрдбрд╝рд╛ рд╕рд░рд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдБред рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рд╕рд╛рде json рдЕрдкрдиреЗ рдШрдЯрдХ рдХреЗ рд╕рд╛рде рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдЭреВрда рд╣реЛрдЧрд╛ред рдФрд░ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреБрдВрдЬрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рд╡рд┐рд╢реЗрд╖ рдЬреЕрд╕рди рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкрде рдХреЗ рдЖрдзрд╛рд░ рдкрд░ json рдмрдВрдбрд▓ рдХреА рд╕рдВрд░рдЪрдирд╛ рдмрдирд╛рдИ рдЬрд╛рдПрдЧреАред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ en.json рд╣реИрдВ, рдПрдХ рдкрде src/app/article-component , рдФрд░ рджреВрд╕рд░рд╛ src/app/comment-component ред рдореИрдВ рдЖрдЙрдЯрдкреБрдЯ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд json рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ:


 { "article-component": { "TITLE": "Article title" }, "comment-component": { "TITLE": "Comment title" } } 

рд╣рдо рдЙрд╕ рдкрде рдХреЗ рднрд╛рдЧ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддрд╛рдХрд┐ рдЪрд╛рдмрд┐рдпрд╛рдВ рд╡рд┐рдЪрд╛рд░реЛрдВ рдореЗрдВ рдпрдерд╛рд╕рдВрднрд╡ рдХрдо рд╣реЛред


!!! рдПрдХ рдЦрд╛рдореА рд╣реИ: рдЬрдм рдЖрдк рдШрдЯрдХ рдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреБрдВрдЬреА рдмрджрд▓ рдЬрд╛рдПрдЧреАред


рдмрд╛рдж рдореЗрдВ рд╣рдо рдПрдХ рдФрд░ рдЬреАрд╡рди рд╣реИрдХ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗ рдЬреЛ рд╣рдореЗрдВ рдШрдЯрдХ рдХреЛ рдХреЗрд╡рд▓ рдЕрдВрддрд┐рдо рдХреБрдВрдЬреА рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛, рднрд▓реЗ рд╣реА рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХрд╣рд╛рдВ рдФрд░ рдХрд┐рддрдиреА рдЧрд╣рд░реА рд╣реИ, рдФрд░ рддрджрдиреБрд╕рд╛рд░ рд╣рдо рдЗрд╕реЗ рдЕрдкрдиреА рдЗрдЪреНрдЫрд╛рдиреБрд╕рд╛рд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЬреИрд╕рд╛ рдЪрд╛рд╣реЗрдВ рд╡реИрд╕рд╛ рдирд╛рдо рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред


рдореВрд▓ рд░реВрдк рд╕реЗ, рдореИрдВ рдПрдирдХреИрдк-рдЯреНрд░рд╛рдВрд╕рд▓реЗрд╢рди рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЗрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдмрд╣реБрд░реВрдкрддрд╛ рдХрд╛ рдПрдХ рд╕рдВрдХреЗрдд рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореБрдЭреЗ рдПрдВрдЧреБрд▓рд░ - рдПрдВрдЧреБрд▓рд░ рд╡реНрдпреВ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди , рдпрд╛ рдмрд▓реНрдХрд┐ рд╢реИрдбреЛ рдбреЛрдо рдореЗрдВ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИред рд╣рд╛рдВ, рдпрд╣ рдПрдХ рдкреВрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдмрдврд╝рд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдПрдирдЬреАрдПрдХреНрд╕-рдЯреНрд░рд╛рдВрд╕рд▓реЗрд╢рди рдХреЗ рдмрд╛рдж рдЕрдзрд┐рдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ, рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрдЦрдж рд╣реЛ рдЧрдпрд╛ рд╣реИред рдШрдЯрдХреЛрдВ рдХреЛ рдХреЗрд╡рд▓ рдЙрдирдХреЗ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд░рд╡рд╛рд╣ рдХрд░рдирд╛ рд╢реБрд░реВ рд╣реБрдЖ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореВрд▓ рдШрдЯрдХ рдореЗрдВ рд╕реНрдерд╛рдиреАрдпрддрд╛рдУрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрд╛рд▓ рдШрдЯрдХ рдореЗрдВ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдм рдЖрдк рдкреНрд░реЛрдЬреЗрдХреНрдЯ рд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдШрдЯрдХреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд╛рдиреАрдп рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЕрдиреНрдп рдЬрдЧрд╣реЛрдВ рдкрд░, рдмрд╛рд░реАрдХрд┐рдпрд╛рдВ рд╣реИрдВ, рдЙрд╕ рдкрд░ рдмрд╛рдж рдореЗрдВред


рддреЛ рдЪрд▓рд┐рдП рдЕрдкрдиреЗ рдкреНрд▓рдЧрдЗрди рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВред рдпрд╣ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдХреИрд╕реЗ рд╣реИ ред рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдкреНрд▓рдЧрдЗрди рд╡рд┐рд▓рдп ред
рд▓реЛрдбрд░ рдФрд░ рдкреНрд▓рдЧрдЗрди рдХреЗ рд▓рд┐рдП рд╕реНрд░реЛрдд рдХреЛрдб рд▓реЗрдЦ рдХреЗ рддрд▓ рдкрд░ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдВрдХ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдлрд╝реЛрд▓реНрдбрд░ ред/build-utils)ред


рдкреНрд▓рдЧрдЗрди рд╕рдм рдХреБрдЫ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдКрдкрд░ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ:


  • рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЗ рдкрде рдХреЗ рдирд╛рдо рдЬрд┐рдиреНрд╣реЗрдВ рдЕрдирджреЗрдЦрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдпрд╣ рдареАрдХ рд╡рд╣ рдХреНрд╖рдг рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкрде рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ)
  • fileInputред рдареЗрд╕ рдореЗрдВ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд (рдЬреИрд╕реЗ рд╡реЗрдмрдкреИрдХ рдореЗрдВ рдкрд░реАрдХреНрд╖рдг)
  • rootDirред рдЬрд╣рд╛рдВ рдлрд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП fileInput рдкреИрдЯрд░реНрди рджреНрд╡рд╛рд░рд╛
  • outputDirред рдЬрд╣рд╛рдВ рдбрд┐рдлреЙрд▓реНрдЯ рдлрд╛рдЗрд▓ рдореЗрдВ рдбрд┐рдлреЙрд▓реНрдЯ рдлрд╛рдЗрд▓ рдФрд░ рд▓реЛрдХрд▓рд╛рдЗрдЬреЗрд╢рди рдмрдирд╛рдП рдЬрд╛рдПрдВрдЧреЗ
  • configNameред рдХреЙрдиреНрдлрд┐рдЧ рдлрд╛рдЗрд▓ рдХрд┐рд╕ рдирд╛рдо рд╕реЗ рдмрдирд╛рдИ рдЬрд╛рдПрдЧреАред

рдореЗрд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рдкреНрд▓рдЧрдЗрди рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ:


 // build-utils.js // part of METADATA { // ... translationsOutputDir: 'langs/', translationsFolder: '@translations', translationsConfig: `config.${Math.random().toString(36).substr(2, 9)}.json`, } //webpack.common.js new MergeLocalizationPlugin({ fileInput: [`**/${METADATA.translationsFolder}/*.json`, 'app-translations/**/*.json'], rootDir: 'src', omit: new RegExp(`app-translations|${METADATA.translationsFolder}|^app`, 'g'), outputDir: METADATA.translationsOutputDir, configName: METADATA.translationsConfig }), 

рдРрд╕реЗ рдШрдЯрдХреЛрдВ рдХреЗ рдЕрдВрджрд░ рдЬрд┐рдиреНрд╣реЗрдВ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдПрдХ @translations рдлрд╝реЛрд▓реНрдбрд░ рд╣реИ, рдЗрд╕рдореЗрдВ en.json, ru, рдЖрджрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред


рдирддреАрдЬрддрди, рдЬрдм рдлрд╝реНрд▓рд┐рдкрд┐рдВрдЧ рд╣реЛрддреА рд╣реИ, рддреЛ рд╕рдм рдХреБрдЫ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдПрдХрддреНрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, @translations рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рдкрде рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдПред рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдмрдВрдбрд▓ рдбрд┐рд╕реНрдЯ / рд▓реИрдВрдЧреНрд╕ / рдореЗрдВ рд╣реЛрдЧрд╛, рдФрд░ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдХреЛ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдирд╛рдо рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред $ {Some-random} .json


рдЕрдЧрд▓рд╛, рд╣рдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВрдЧреЗ рдХрд┐ рд╡рд╛рдВрдЫрд┐рдд рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдмрдВрдбрд▓ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдПрдХ рдирд╛рдЬреБрдХ рдХреНрд╖рдг рд╣реИ - рдХреЗрд╡рд▓ рд╡реЗрдмрдкреИрдХ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдФрд░ рдХреЙрдиреНрдлрд┐рдЧ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдирд╛рдо рдХреЗ рдкрде рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реИ, рдЖрдЗрдП рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦреЗрдВ рддрд╛рдХрд┐ рдирд╡реАрдирддрдо рдбреЗрдЯрд╛ AppTranslateLoader рдореЗрдВ рд╣реЛ рдЬрд╛рдП рдФрд░ рджреЛ рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рдирд╛рдо рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛред


 // some inmports // ... // momentJs import * as moment from 'moment'; import 'moment/locale/en-gb'; import 'moment/locale/ru'; @Injectable() export class AppTranslateLoader { //            public additionalStorageKey: string = ''; private translationsDir: string; private translationsConfig: string; private selectedLang: string; private fallbackLang: string; private loadedLang: string; private config: { [key: string]: string; } = null; private loadSubs = new Subscription(); private configSubs = new Subscription(); private loadSubj = new Subject(); private get storageKey(): string { return this.additionalStorageKey ? `APP_LANG_${this.additionalStorageKey}` : 'APP_LANG'; } constructor(private http: HttpClient, private translate: TranslateService) { //   webpack       //     . this.translationsDir = `${process.env.TRANSLATE_OUTPUT}`; this.translationsConfig = `${process.env.TRANSLATE_CONFIG}`; this.fallbackLang = 'en'; const storedLang = this.getUsedLanguage(); if (storedLang) { this.selectedLang = storedLang; } else { this.selectedLang = translate.getBrowserLang() || this.fallbackLang; } } } 

process.env.TRANSLATE_OUTPUT рдмрд╕ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рд╣рдореЗрдВ рд╡реЗрдмрдкреИрдХ (DefinePlugin рдпрд╛ EnvironmentPlugin) рдореЗрдВ рдПрдХ рдФрд░ рдкреНрд▓рдЧрдЗрди рдШреЛрд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


 // METADATA declaration const METADATA = { translationsOutputDir: 'langs/', translationsFolder: '@translations', translationsConfig: `config. ${Math.random().toString(36).substr(2, 9)}.json`, }; // complex webpack config... // webpack plugins... new DefinePlugin({ 'process.env.TRANSLATE_OUTPUT': JSON.stringify(METADATA.translationsOutputDir), 'process.env.TRANSLATE_CONFIG': JSON.stringify(METADATA.translationsConfig), }), 

рдЕрдм рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕реНрдерд╛рди рдкрд░ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХреЗ рдирд╛рдо рдХрд╛ рдорд╛рд░реНрдЧ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рд╡реЗрдмрдкреИрдХ рдЕрд╕реЗрдВрдмрд▓реА ( ng eject ) рдореЗрдВ рдЙрддреНрдкрдиреНрди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдПрдВрдЧреБрд▓рд░ рд╕реЗрд▓рд┐рдВрдЧ рд╕реЗ, рдЖрдк рдХреЛрдб рд╕реЗ process.env.someValue (рднрд▓реЗ рд╣реА рдЖрдк DefinePlugin рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ) рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ, рдХрдВрдкрд╛рдЗрд▓рд░ рд╢рдкрде рд▓реЗ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ 2a рд╢рд░реНрддреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


  • рдореЗрдВ main.ts рдкрд╣рд▓реА рдкрдВрдХреНрддрд┐ /// <reference types="node"/> рдЬреЛрдбрд╝реЗрдВ /// <reference types="node"/>
  • package.json рдореЗрдВ @types/node - npm install --save-dev @types/node - npm install --save-dev @types/node ред

рд╣рдо рд╕реАрдзреЗ рдмреВрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред
рдпрджрд┐ рдЖрдк APP_INITIALIZER рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░реЙрдорд┐рд╕ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ, рди рдХрд┐ рдЕрд╡рд▓реЛрдХрди рдпреЛрдЧреНрдпред рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдп рдПрдХ рдХреНрд╡реЗрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рд▓рд┐рдЦрдирд╛ рд╣реИ:


  • рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ config.json рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ (рдХреЗрд╡рд▓ рд▓реЛрдб рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░)ред
  • рдЙрд╕ рднрд╛рд╖рд╛ рдХреЛ рд▓реЛрдб рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдХреА рднрд╛рд╖рд╛ рд╣реИ
  • рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдбрд╛рдЙрдирд▓реЛрдб рднрд╛рд╖рд╛ рдХреЗ рд╕рд╛рде рдХрдордмреИрдХ рддрд░реНрдХ рдкреНрд░рджрд╛рди рдХрд░реЗрдВред

 // imports @Injectable() AppTranslateLoader { // fields ... //    ,         //      ,   // Subscription    unsubscribe    //   private loadSubs = new Subscription(); private configSubs = new Subscription(); //       -   // Subject       private loadSubj = new Subject(); // constructor ... //  Promise! public loadTranslation(lang: string = ''): Promise<any> { if (!lang) { lang = this.selectedLang; } //       if (lang === this.loadedLang) { return; } if (!this.config) { this.configSubs.unsubscribe(); this.configSubs = this.http.get<Response>(`${this.translationsDir}${this.translationsConfig}`) .subscribe((config: any) => { this.config = config; this.loadAndUseLang(lang); }); } else { this.loadAndUseLang(lang); } return this.loadSubj.asObservable().toPromise(); } private loadAndUseLang(lang: string) { this.loadSubs.unsubscribe(); this.loadSubs = this.http.get<Response>(`${this.translationsDir}${this.config[lang] || this.config[this.fallbackLang]}`) .subscribe(res => { this.translate.setTranslation(lang, res); this.translate.use(lang).subscribe(() => { this.onLangLoaded(lang); }, // fallback  ngx-translate   (err) => this.onLoadLangError(lang, err)); }, // fallback  http   (err) => this.onLoadLangError(lang, err)); } private onLangLoaded(newLang: string) { //     if (this.loadedLang && this.loadedLang !== newLang) { this.translate.resetLang(this.loadedLang); } this.loadedLang = newLang; this.selectedLang = newLang; // TODO:       //     ,       //  en  ru,  momentJs   en. moment().locale(newLang); //  .  momentJs localStorage.setItem(this.storageKey, newLang); //   ls this.loadSubj.complete(); //   -      . } private onLoadLangError(langKey: string, error: any) { //   ,      if (this.loadedLang) { this.translate.use(this.loadedLang) .subscribe( () => this.onLangLoaded(this.loadedLang), (err) => this.loadSubj.error(err)); //    } else if (langKey !== this.fallbackLang) { //      fallback  this.loadAndUseLang(this.fallbackLang); } else { //    this.loadSubj.error(error); } } 

рд╣реЛ рдЧрдпрд╛ред


рдЕрдм рдШрдЯрдХреЛрдВ рдХреЛ рдЕрдиреНрдп рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛, рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рдФрд░ рдмрд╣реБрд░реВрдкрддрд╛ рдХреА рд╕рдорд╛рдирддрд╛ред


рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рд╕реА рддрд░рд╣ рдХрд╛ рдПрдирдХреИрдкреНрд╕реБрд▓реЗрд╢рди рд╣реИред рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреЛ рдШрдЯрдХреЛрдВ рдХреЗ рдмрдЧрд▓ рдореЗрдВ рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ рдзрдХреЗрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╕рднреА рдкреНрд░рдореБрдЦ рдкрде рдЕрджреНрд╡рд┐рддреАрдп рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╣рдо рдЕрднреА рднреА рдХреБрдЫ-рдШрдЯрдХ 2 рдХреЗ рдЕрдВрджрд░ рдХреБрдЫ-рдШрдЯрдХ 1 рдШрдЯрдХ рдХреА рдХреБрдВрдЬреА рдХреЛ рд╕реНрдерд╛рдиреАрдп рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд╕рдм рдХреБрдЫ рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛, рд╣рдо рдмрд╛рдж рдореЗрдВ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВрдЧреЗред


 <some-component1 [someLabel]="'components.some-component2.some_key' | tanslate"></some-component1> // components.some-component2 -     

рдШрдЯрдХреЛрдВ рдХреА рдЧрддрд┐ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ:
рдЕрдм рдЬреЛ рдХреБрдВрдЬреА рд╣рдо рджреГрд╢реНрдп рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рд╡рд╣ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкрде рд╕реЗ рдХрдареЛрд░рддрд╛ рд╕реЗ рдЬреБрдбрд╝реА рд╣реБрдИ рд╣реИ рдФрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрд░рдЪрдирд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИред


рдореИрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рджреБрдЦрдж рдорд╛рдорд▓рд╛ рдмрддрд╛рдКрдВрдЧрд╛:


 <div translate="+lazy-module.components.article-component.article_title"></div> 

рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рдореИрдВ рдШрдЯрдХ рдлрд╝реЛрд▓реНрдбрд░ рдХрд╛ рдирд╛рдо рдкреЛрд╕реНрдЯ-рдШрдЯрдХ рдХреЗ рд▓рд┐рдП рдмрджрд▓реВрдВ?
рд╕рднреА рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╕реНрдерд╛рдиреЛрдВ рдореЗрдВ рдЗрд╕ рдХреБрдВрдЬреА рдХреЛ рджрд░реНрдЬ рдХрд░рдирд╛ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реЛрдЧрд╛ред рдмреЗрд╢рдХ, рдХрд┐рд╕реА рдиреЗ рднреА рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рдХреЛ рд░рджреНрдж рдирд╣реАрдВ рдХрд┐рдпрд╛ рдФрд░ рдвреВрдВрдврд╛-рдмрджрд▓рд╛ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдЖрдИрдбреАрдИ рдХреЗ рд╕рдВрдХреЗрддреЛрдВ рдХреЗ рдмрд┐рдирд╛ рдпрд╣ рд▓рд┐рдЦрдирд╛ рднреА рддрдирд╛рд╡рдкреВрд░реНрдг рд╣реИред


рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╡реЗрдмрдкреИрдХ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реИ? рд╡реЗрдмрдкреИрдХ рд▓реЛрдбрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдРрд╕реА рдЪреАрдЬ рд╣реИ, рдРрд╕реЗ рдХрдИ рд▓реЛрдбрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ рдЬреЛ рдлрд╝рд╛рдЗрд▓ рдкрдереЛрдВ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ: рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕реАрдПрд╕рдПрд╕ рдореЗрдВ рд╕рдВрд╕рд╛рдзрди рдкрде - рд╡реЗрдмрдкреИрдХ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рд╣рдо рд╕рд╛рдкреЗрдХреНрд╖ рдкреГрд╖реНрдарднреВрдорд┐-рдЫрд╡рд┐ рдкрде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: url (../ рд░рд┐рд╢реНрддреЗрджрд╛рд░.png), рдФрд░ рдЗрд╕реА рддрд░рд╣ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдмрд╛рдХреА рдлрд╝рд╛рдЗрд▓ рдкрде рд╣рд░ рдЬрдЧрд╣ рд╣реИрдВ!


рдЬрд┐рд╕рдиреЗ рднреА рдЕрдкрдирд╛ рд╡реЗрдмрдкреИрдХ рдмрдирд╛рдпрд╛ рд╣реИ рд╡рд╣ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рд▓реЛрдбрд░ рдЗрдирдкреБрдЯ рдкрд░ рдПрдХ рдлрд╛рдЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреИрдЯрд░реНрди рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИред рд▓реЛрдбрд░ рдХрд╛ рдХрд╛рд░реНрдп рд╕реНрд╡рдпрдВ рдХрд┐рд╕реА рддрд░рд╣ рдЗрд╕ рдЗрдирдкреБрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрджрд▓рдирд╛ рдФрд░ рдЕрдиреНрдп рд▓реЛрдбрд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдЖрдЧреЗ рдХреЗ рдмрджрд▓рд╛рд╡ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рд╣реИред


рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдЕрдкрдиреЗ рд▓реЛрдбрд░ рдХреЛ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред рд╕рд╡рд╛рд▓ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕ рддрд░рд╣ рдХреА рдлрд╛рдЗрд▓реЗрдВ рдмрджрд▓реЗрдВрдЧреЗ: рд╡рд┐рдЪрд╛рд░ рдпрд╛ рдШрдЯрдХ? рдПрдХ рддрд░рдл, рд╡рд┐рдЪрд╛рд░ рд╕реАрдзреЗ рдШрдЯрдХ рдореЗрдВ рдФрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рджреГрд╢реНрдпреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдкрд░реНрдпрд╛рдкреНрдд рдФрд░ рдХрдард┐рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рджреГрд╢реНрдп рд╣реИ рдЬрд╣рд╛рдВ 100 рдЕрдиреБрд╡рд╛рдж рдирд┐рд░реНрджреЗрд╢ рд╣реИрдВ (рд▓реВрдк рдореЗрдВ рдирд╣реАрдВ):


 <div id="1">{{'./some_key_1' | translate}}</div> ... <div id="100">{{'../another_key_!' | translate}}</div> 

рд▓реЛрдбрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рдЗрдк рдпрд╛ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рдкрд╛рд╕ рдШрдЯрдХ рд╕реНрдерд╛рдиреАрдпрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрде рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


 <div id="1">{{'app.some-component.some_key_1' | translate}}</div> // app.some-component. -   loader' 

рд╣рдо рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдШрдЯрдХ рдореЗрдВ рдПрдХ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:


 @Component({ selector: 'app-some', template: '<div>{{(localization + 'key') | tanslate}}</div>' }) export class SomeComponent { localization = './' } 

рдпрд╣ рднреА рдмреБрд░рд╛ рд╣реИ - рдЖрдкрдХреЛ рд╣рд░ рдЬрдЧрд╣ рдПрдХ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдХреБрдВрдЬреА рд░рдЪрдирд╛ рдХрд░рдиреА рд╣реЛрдЧреАред


рдЪреВрдВрдХрд┐ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╡рд┐рдХрд▓реНрдк рдЦрд░рд╛рдм рджрд┐рдЦрддреЗ рд╣реИрдВ, рдбреЗрдХреЛрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ рдФрд░ рдШрдЯрдХ рдХреЗ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдореЗрдВ рдХреБрдЫ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЛ рдмрдЪрд╛рдПрдВ (рдЬреИрд╕рд╛ рдХрд┐ рдХреЛрдгреАрдп рдХрд░рддрд╛ рд╣реИ)ред


рдЫрд╡рд┐


рдПрдиреЛрдЯреЗрд╢рди - рдХреЛрдгреАрдп рд╕рдЬреНрдЬрд╛рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛рдбреЗрдЯрд╛
__app_annotations__ - рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдЬрд┐рд╕реЗ рд╣рдо рдЕрдкрдиреЗ рд▓рд┐рдП рд╕реНрдЯреЛрд░ рдХрд░реЗрдВрдЧреЗ


рдШрдЯрдХ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рд╕реНрдерд╛рдиреАрдпрдХрд░рдг рдлрд╝реЛрд▓реНрдбрд░ рдХрд╛ рдорд╛рд░реНрдЧ рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрд╕реА рдбреЗрдХреЛрд░реЗрдЯрд░ рдХреЛ рдкрде рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


 //translate.service.ts const app_annotations_key = '__app_annotations__'; export function Localization(path: string) { // tslint:disable-next-line:only-arrow-functions return function (target: Function) { const metaKey = app_annotations_key; Object.defineProperty(target, metaKey, { value: { //         path. path, name: 'Translate' } } as PropertyDescriptor); }; } //some.component.ts @Component({...}) @Localization({ path: './', otherOptions: {...} }); export class SomeComponent { } 

webpack, loader , - . , ( styleUrls) . loader, npm . .


, -. , -.


 <div>{{'just_key' | translate}}</div> 

. , , , . тАФ Injector, . , Injector, '' , translate . Injector, ( ), 'get'.


рдЫрд╡рд┐


, parent , , Injector'a , , , , , .


, API, forwarRef() ( Angular reactive forms, control ). , . .


 // translate.service.ts export const TRANSLATE_TOKEN = new InjectionToken('MyTranslateToken'); // app.component.ts @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [{provide: TRANSLATE_TOKEN, useExisting: forwardRef(() => AppComponent)}] }) @Localization('./') export class AppComponent { title = 'app'; } 

, , , forwardRef().


, Injector forwardRef() , . , '' . , , .


 // my-translate.directive.ts @Directive({ // tslint:disable-next-line:directive-selector selector: '[myTranslate]' }) export class MyTranslateDirective extends TranslateDirective { @Input() public set myTranslate(e: string) { this.translate = e; } private keyPath: string; constructor(private _translateService: TranslateService, private _element: ElementRef, _chRef: ChangeDetectorRef, //    forwardRef() @Inject(TRANSLATE_TOKEN) @Optional() protected cmp: Object) { super(_translateService, _element, _chRef); //    const prototype = Object.getPrototypeOf(cmp || {}).constructor; if (prototype[app_annotations_key]) { //      this.keyPath = prototype[app_annotations_key].path; } } public updateValue(key: string, node: any, translations: any) { if (this.keyPath) { //     ,   //   key = `${this.keyPath.replace(/\//, '.')}.${key}`; } super.updateValue(key, node, translations); } } 

.


- :


 <div>{{'just_this_component_key' | myTranslate}}</div> //  <div myTranslate="just_this_component_key"></div> 

translate , . , , - :


 //en.bundle.json { "global_key": "Global key" "app-component": { "just_key": "Just key" } } //some-view.html <div translate="global_key"></div> 

Research and improve!


full example


:


  1. FE node.js stacktrace.js.
  2. Jest Angular .
  3. Web worker ) , , Angular .

Source: https://habr.com/ru/post/hi413787/


All Articles