用Renderer做i18n?

时间:2016-02-24 15:57:19

标签: internationalization angular

我最近阅读了@yearofmoo关于Angular2 Renderer的very interesting article。它给了我一个想法,可以用Renderer做i18n。基本上使用此功能:

  createText(parentElement: any, value: string): any {
    // this is called for every text node in the template
  }

并通过将value映射到不同的语言来简单地转换let es = { "Hello": "Hola" } value = "Hello" value = es[value]

With Table_1 (Manager, Employee, Cost) as (
    Select 'Donald Torres'  , 'Pamela Jordan'  , 7250.78   UNION ALL
    Select 'Pamela Jordan'  , 'Harry Rivera'   , 36721.39  UNION ALL
    Select 'Pamela Jordan'  , 'Ryan Mcdonald'  , 5593.89   UNION ALL
    Select 'Harry Rivera'   , 'Bruce Mccoy'    , 3538.19   UNION ALL
    Select 'Ryan Mcdonald'  , 'Shirley Ortiz'  , 137.20     UNION ALL
    Select 'Ryan Mcdonald'  , 'Roger Gardner'  , 9140.34   UNION ALL
    Select 'Ryan Mcdonald'  , 'Paula Richards' , 135109.59 UNION ALL
    Select 'Paula Richards' , 'Andrew Boyd'    , 106676.77
),
CTE as
    (
        select Manager as Manager, Employee as Employee, 1 as Level, Cost as Cost
        from Table_1
        Union All
        select C.Manager, T.Employee, C.Level + 1, T.Cost
        from CTE as C inner join Table_1 as T on C.Employee = T.Manager
    )

select Manager, 
       Employee, 
       T_Cost = Cost + isnull((select SUM(Cost) 
                               from CTE C2 
                               where C2.Manager = C1.Employee)
                             ,0) 
from CTE C1 
where Level = 1

我简要地看了一眼issuesdesign docs,但在走下这个兔子洞之前,我想检查一下是否有人有这方面的经验。

是否有任何问题可能导致无法正常工作?在我不知道的方式上有一些突破性的变化?关于这种方法的意见?

2 个答案:

答案 0 :(得分:1)

我们使用Renderer设置属性提供的翻译。

import { Directive, ElementRef, Input, Renderer, OnInit} from '@angular/core';
import { TranslateService } from './translate.service';

@Directive({ selector: '[translate]' })
export class TranslateDirective  implements OnInit{

    @Input() translate :string;

   constructor(private el: ElementRef, private renderer: Renderer, private _translateService : TranslateService) {}

   ngOnInit(): void {
        this.renderer.setText(this.el.nativeElement,this._translateService.instant(this.translate));
   }
}

请参阅plunker了解演示

希望这就是你在寻找的地方。

答案 1 :(得分:0)

这是一个老问题,但也许其他人会偶然发现它。 :)

我也意识到 Angular 有内置的 i18n 机制,但由于一些原因我们不想使用它们。主要是因为我们在另一个产品中已经有数以千计的翻译短语映射,我们希望重用所有这些。所以我们将现有的映射转换成json,然后在我们的angular项目中:

  1. 使用如下函数创建服务(例如 I18nService):
export class I18nService {
    phraseMap: Map<string, string>; // fill this however you like

    translatePage(elements: QueryList<ElementRef>, renderer: Renderer2) {
        elements.forEach((el: ElementRef) => {
           let key:string = el.nativeElement.innerText;
           let phrase = this.phraseMap.get(key);
           if (phrase) {
              renderer.setProperty(el.nativeElement, 'innerText', phrase);
           }
        }
    }

// ...

this.phraseMap 是一个 Map,其值类似于 key: "PH_HELLO" value: "Bonjour"

在你的组件模板中,用模板变量装饰你的元素(我使用了#i18n,但可以是任何东西),并用你的短语键替换文本,例如:

   <span #i18n>PH_HELLO</span>
   <div #i18n>PH_LOGOUT</div>

在您的组件类中,使用 ViewChildren 收集所有适当的元素。注入你的服务和一个 Angular Renderer2,并实现 AfterViewInit:

export class MyComponent implements AfterViewInit {

   @ViewChildren('i18n', {read:ElementRef}) i18nElements: QueryList<ElementRef>;

   constructor(
      private i18nService: I18nService,
      private renderer: Renderer2 // from @angular/core
   ) {}

   ngAfterViewInit() {
      this.i18nService.translatePage(this.i18nElements, this.renderer);
   }