angular - 是否可以在不从 DOM 读取的情况下在 Angular 中读取元素的文本内容?

标签 angular internationalization angular-directive

我需要能够在我的 Angular 应用程序中的代码中使用翻译后的字符串,但是由于国际化工具还不能胜任这项任务,我实现了一个有点老套的版本,它利用了 Angular 现有的国际化功能,目的是逐步淘汰我的原生 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 吗?

最佳答案

看起来你的复杂性很大一部分是因为你想支持动态文本——文本可能会在运行时改变。我认为您不需要这样做,因为 i18n 文本需要是静态的,以便:

  1. 可以在编译时提取。

  2. 它可以提前翻译,你可以在以后的编译时存储所有的翻译。

您的示例“今天是...”是不可翻译文本的完美示例。 :-) 您应该将其更改为仅让“今天是”本身成为一个文本 block ,然后将日期与当前语言环境一起显示在 范围内。

关于angular - 是否可以在不从 DOM 读取的情况下在 Angular 中读取元素的文本内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47895802/

相关文章:

.net - .NET 中文本文件资源的本地化

javascript - 可以为日语网站生成相关文章列表的第三方工具

angular2-template - 当未在NgIf中呈现时,删除角度4中的验证

angular - cdkDropListSortingDisabled 属性无法绑定(bind),因为它是 cdkDropList 指令的未知属性。 Angular Material

html - 如何在 Angular 12 中制作 Material-UI 输入文本字段 "read only"

angular - 如何获取 ngFor 数组的 DOM 元素?

angular - activatedRoute 快照在 TS 类构造函数中不起作用

variables - 走向国际化(i18n)

html - 如何使用带有 Angular 的字符串数组在 HTML 模板中显示包含 3 列的表格?

javascript - 如何在 PEERJS 和 Angular 4 上列出要连接到视频聊天的对等点?