【发布时间】:2018-06-02 09:49:58
【问题描述】:
我需要能够在我的 Angular 应用程序的代码中使用翻译后的字符串,但由于 i18n 工具还不能胜任这项任务,我实现了一个稍微有点 hacky 的版本,它利用了 Angular 现有的 i18n 功能,目的是逐步淘汰我的原生 Angular 解决方案,因为它的 i18n 功能可以满足我的需求(应该是 5.x release,手指交叉)。
基本上,我有一个 TranslationDirective 从 DOM 读取文本,并在文本更改时发出事件:
@Directive({
selector: '[myAppTranslation]'
})
export class TranslationDirective implements AfterViewChecked, OnChanges {
/**
* dependencies takes an array of the values needed to calculate the output translation
* we use this for change detection, to minimize the DOM interaction to only when it is necessary
*/
@Input() dependencies: any[];
isDirty = true;
@Input() messageKey: string;
message: string;
@Output() messageUpdated = new EventEmitter<TranslationEvent>();
constructor(public el: ElementRef) {}
/**
* sets the translated message and triggers the TranslationEvent
*/
setMessage() {
const message = (this.el.nativeElement.textContent || '').trim();
const oldMessage = (this.message || '');
if (oldMessage !== message) {
this.message = message;
this.isDirty = false;
this.triggerTranslationEvent();
}
}
ngOnChanges() {
this.isDirty = true;
}
ngAfterViewChecked() {
if (this.isDirty) {
this.setMessage();
}
}
/**
* triggers the messageUpdated EventEmitter with the TranslationEvent
*/
triggerTranslationEvent() {
// need to delay a tick so Angular doesn't throw an ExpressionChangedAfterItHasBeenCheckedError
setTimeout(() => {
const event = new TranslationEvent(this.messageKey, this.message);
this.messageUpdated.emit(event);
});
}
}
export class TranslationEvent {
constructor(public messageKey: string, public message: string) {}
}
这样使用:
<span
myAppTranslation
i18n
[dependencies]="[today]"
[messageKey]="todaysDateKey"
(messageUpdated)="setTodaysDateTranslation($event)"
>
Today is {{today | date:'short'}}
</span>
由于要翻译的字符串都驻留在模板中,Angular 的 xi18n 工具可以很好地读取它们,Angular 编译器会将它们替换为翻译后的字符串。
这是实用的,但不是很好。我怀疑有一个计时错误正等着咬我,但还没有表现出来。有一个效率低下且缓慢的写入到 DOM-从 DOM 读取的循环,如果消除这种循环非常好。
如果我能避免的话,我希望能够通过绕过 DOM 来消除一个问题来源。 Angular 是否会保留一个元素内容的内存副本,无需通过 DOM 即可访问?如果可以的话,我可以避免将翻译元素完全写入 DOM 吗?
【问题讨论】:
-
使用 ngModel 怎么样?并请提供 plunker 链接
标签: angular internationalization angular-directive