是否可以在不从 DOM 读取的情况下在 Angular 中读取元素的文本内容?
Posted
技术标签:
【中文标题】是否可以在不从 DOM 读取的情况下在 Angular 中读取元素的文本内容?【英文标题】:Can the text content of an element be read in Angular without reading from the DOM? 【发布时间】: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 链接 【参考方案1】:看起来您的很多复杂性是因为您想要支持动态文本 - 文本可能会在运行时更改。我认为您不需要这样做,因为 i18n 文本需要是静态的,以便:
可以在编译时提取。
可以提前翻译,所有翻译都存储在以后的编译时。
您的示例“今天是……”是不可翻译文本的完美示例。 :-) 您应该将其更改为仅将“今天是”本身作为文本块,然后将日期显示为当前区域设置超出该跨度。
【讨论】:
Angular 的 i18n 工具支持该格式的翻译。需求来自期望通过配置对象传递文本的第 3 方库,我需要翻译该文本。 哇,我的错,我不知道 Angular i18n 工具可以处理这个问题。但是,您使用了 double-,所以在调用 myAppTranslation 指令之前,不是让 Angular 动态评估表达式吗? 是的,它将在指令被调用之前被评估——这是重点的一部分。示例用例包括需要本地化的日期。将日期附加到翻译的字符串不是一种选择,因为翻译可以在不同语言的字符串中移动日期的位置。以上是关于是否可以在不从 DOM 读取的情况下在 Angular 中读取元素的文本内容?的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在不从原始源重新索引的情况下更改 Solr 架构中指定的分析器?
如何在不使用用户设置的情况下在运行时读取/写入 app.config 设置?
如何在不使用数据集的情况下在 Matlab 上比较不同的面部图像?
是否可以在不安装 Python 的情况下在 Windows 上安装 Robot Framework?