嵌入式c int转字符串_如何将角度分量嵌入transloco翻译字符串中

嵌入式c int转字符串

“What? Isn’t the application available in Swedish?”

“什么? 瑞典语不可用吗?”

I was talking to my accountant on the phone, but I could literally hear him cringe none the less.

正在和我的会计师通话,但我确实能听到他的畏缩。

Earlier that week, I had shown it to my stepfather and gotten the same reaction from him. And come to think of, didn’t my buddy Mike make a remark about this as well?

那周早些时候,我把它给了继父,并得到了他的同样React。 想一想,我的好友迈克(Mike)也没有对此发表评论吗?

So far, my application had been English only. With a global aim, it felt natural. And these days, most people are comfortable enough with the English language, so there shouldn’t really be necessary to translate it, right?

到目前为止,我的申请仅是英语。 出于全球目标,这很自然。 如今,大多数人对英语已经足够适应了,所以真的不需要翻译它,对吗?

Think again.

再想一想。

Of course, it depends on what kind of application you are offering. But if you are targeting a traditional market segment as I do, you better face the music.

当然,这取决于您提供的应用程序类型。 但是,如果您像我一样瞄准传统细分市场,则最好面对音乐。

Flowmine, as my product is called, is an ERP application. It’s all about fun admin stuff like time-tracking, expense reporting, accounting, and invoicing.

我的产品Flowmine是一个ERP应用程序。 一切都与有趣的管理员相关,例如时间跟踪,费用报告,会计和发票。

And while I might beat a lot of my competition in terms of UX and general look and feel, they still had one thing I didn’t:

尽管我可能会在用户体验和总体外观上击败很多竞争对手,但他们仍然有我没有的一件事:

Internationalized applications. They were available in Swedish. Finnish. German.

国际化的应用 。 它们提供瑞典语版本。 芬兰。 德语。

While the fintech industry is evolving fast in terms of technology, it’s also very traditional when it comes to processes and terminology. At least many of the people who are using the products are.

尽管金融科技行业的技术发展日新月异,但在流程和术语方面也非常传统。 至少有许多使用该产品的人。

And maybe rightly so — the financial domain can be very complex, and I fully understand that a user might be reluctant to learn a bunch of new English words just because the developers of the application were too lazy to translate it.

也许是对的-金融领域可能非常复杂,我完全理解用户可能不愿意学习一堆新的英语单词,只是因为应用程序的开发人员太懒惰而无法翻译它。

让我们国际化 (Let’s internationalize)

So — long story short — I had to bite the bullet and internationalize Flowmine. The question remaining was how to do it.

因此,长话短说,我不得不硬着头皮对Flowmine进行国际化。 剩下的问题是如何做到这一点。

Since the frontend is an Angular application, I basically had four options:

由于前端是Angular应用程序,因此我基本上有四个选择:

  • The official @angular/localize package

    官方@ angular / localize包
  • ngx-translate

    ngx翻译
  • Transloco

    Transloco
  • Roll my own

    自己滚

The official package is probably super-duper-powerful once you wrap your head around it, but it just didn’t click for me.

官方程序包将其包裹住后,可能具有超强力功能,但对我而言并没有点击。

And while I had read a lot of positive things about ngx-translate in the past, the word “discontinued” popped up one time too many for me to be comfortable with it.

而且,尽管我过去曾阅读过许多有关ngx-translate的正面信息,但“停产”一词突然弹出了太多,令我不满意。

Having rolled my own translation framework for the backend, I was leaning towards that route.

在为后端开发了自己的翻译框架之后,我便倾向于这条路。

But then I watched the video tutorials on Transloco by Shahar Kazaz and tried out the framework myself.

但后来我看了视频教程Transloco通过沙哈尔Kazaz并尝试了框架自己。

And what can I say it was love at first sight.

我能说什么 - 那是一见钟情。

Today, I have spent around two weeks with Transloco, and I’m super impressed. Shahar, Netanel Basal, Itay Oded and the other guys contributing have made an awesome framework.

今天,我在Transloco待了大约两个星期,我印象深刻。 Shahar, Netanel BasalItay Oded和其他贡献者建立了一个很棒的框架。

The only thing I missed was the ability to embed Angular components in translation strings, so here’s my solution for that.

我唯一想念的就是能够将Angular组件嵌入翻译字符串中,因此这是我的解决方案。

HTML嵌入问题 (The HTML embedding problem)

A common internationalization problem is that you want to include markup inside your translation string. And while that works fine as long as it’s just simple markup, it does *not* work for Angular components (at least as long as you want to use AOT).

常见的国际化问题是您想在翻译字符串中包含标记。 尽管这工作得很好,只要它只是简单的标记,它*不*对角分量(至少只要你想使用AOT)工作。

As the documentation puts it, we have two choices:

正如文档所述,我们有两种选择:

  • Transform your component into a web component using @angular/elements and use the HTML tag in your translation.

    使用@ angular / elements将组件转换为Web组件,并在翻译中使用HTML标记。
  • Separate your translation into two parts and insert the desired component between them.

    将翻译分为两部分,然后在其中插入所需的组件。

For me, none of these options felt like a good fit for my use case. I simply wanted to be able to insert link tags with Angular attributes at arbitrary places in my translation strings, and simultaneously have the ability to use parameterized translations inside those tags.

对我来说,这些选择都不适合我的用例。 我只是希望能够在翻译字符串的任意位置插入具有Angular属性的链接标签,并同时能够在这些标签内使用参数化翻译。

Put another way:

换一种方式:

Parameterized translations within parameterized translations.

参数化翻译中的参数化翻译。

Put yet another way, to produce output like this, where the link is embedded in the text:

换句话说,产生这样的输出,链接被嵌入到文本中:

Sure, you could break up the translation in multiple parts as suggested by the docs, but that would potentially harm readability. As soon as you introduce a language with a different sentence structure than your default language, you might be forced to use language like this:

当然,您可以按照文档的建议将翻译分为多个部分,但这可能会损害可读性。 引入一种与默认语言不同的句子结构的语言后,您可能会被迫使用以下语言:

<div>
This project is part of an invoice and cannot be edited. <a […]>Click here to see the invoice</a>.
</div>

To me, this latter kind of language just doesn’t read as well as the former example, where the link is part of the natural flow of the language.

对我来说,后一种语言的阅读效果不及前一个示例,后者是该语言自然流程的一部分。

This leaves us with the web component option. But what if you don’t want to introduce another layer of complexity? (Or if you haven’t gotten around to learn web components properly yet, like me…)

这使我们有了Web组件选项。 但是,如果您不想引入另一层复杂性怎么办? (或者,如果您还没有像我这样正确地学习Web组件,那么……)

There must be an easier way around this, right?

必须有一个更简单的方法,对吗?

Sure. Albeit a bit hacky, we can solve it with a regular Angular component and some Vanilla JS. Here’s how I did it.

当然。 尽管有点骇人听闻,但我们可以使用常规的Angular组件和一些Vanilla JS来解决它。 这是我的方法。

我的解决方案-自定义翻译组件 (My solution — a custom translation component)

Before diving into the source of the component, here’s what it looks like in action when it’s being used in the wild:

在深入探讨组件的来源之前,下面是在野外使用组件时的实际效果:

Listing 1, a real-world example
清单1,一个真实的例子

The interesting part of the above is the app-translate component, the rest is just included to provide some context. (It shows a warning to the user that the project is locked for editing since it’s already been billed.)

上面有趣的部分是app-translate组件,其余部分只是为了提供一些上下文。 (它向用户显示警告,因为该项目已经计费,因此该项目已被锁定以进行编辑。)

Just like a regular Transloco Translation API call, this component takes three arguments (in the form of attributes): key, params and scope.

就像常规的Transloco Translation API调用一样,此组件采用三个参数(以属性的形式): keyparamsscope

This means that the actual translation is located in a scoped JSON file, like so:

这意味着实际的转换位于范围限定的JSON文件中,如下所示:

/i18n/project/en.json

And inside that file, I have these keys:

在该文件中,我具有以下键:

"edit": {
"belongsToInvoice": {
"restrictionInfo": "This project is part of {{link}}. Hence, you can only edit estimated hours, deadline, status, and notes.",
"linkText": "invoice {{invoice}}",
"stillOpen": "Please note that you can still add tasks and track time on this project, as long as it's not marked as completed."
}

Notice that the {{link}} parameter in the translation file has a corresponding span tag in the gist in listing 1, with the attribute data-param=”link”.

请注意,转换文件中的{{link}}参数在清单1的要点中具有相应的span标签,其属性为data-param =” link”

What happens next is simply that the app-translate component injects the embedded span tag in the {{link}} placeholder, using content projection.

接下来发生的事情是,简单的app-translate组件使用内容投影将嵌入的span标签注入到{{link}}占位符中。

It looks like this:

看起来像这样:

Let’s begin with the HTML template. It defines a container and a target, where the former holds one or several embedded spans with data-param attributes inside the ng-content tag.

让我们从HTML模板开始。 它定义了一个容器和一个目标,其中前者在ng-content标签内保存一个或多个具有数据参数属性的嵌入式范围。

During component init, we set up an observable that combines Transloco’s langChanges$ with our own initialized$ subject.

在组件初始化期间,我们设置了一个可观察对象,该对象将TranslocolangChanges $与我们自己的Initialized $主题组合在一起。

The reason for this is to let Angular do its content projection magic before starting to move things around in the DOM.

这样做的原因是让Angular在开始在DOM中移动内容之前先进行内容投影魔术。

Without the setTimeout() and ChangeDetectorRef’s detectChanges() calls, we would get the dreaded ExpressionChangedAfterItHasBeenCheckedError.

没有setTimeout()ChangeDetectorRefdetectChanges()调用,我们将得到可怕的ExpressionChangedAfterItHaHasBeenCheckedError

So, in ngAfterViewInit, we kick things off by emitting true to the initialized$ subject.

因此,在ngAfterViewInit中 ,我们通过向初始化的$主题发出true来开始事情。

This, in turn, calls the renderParam() function for each and every embedded span.

反过来,这将为每个嵌入的范围调用renderParam()函数。

We clear any existing children in the #target span by settings innerHTML to an empty string, an then we simply append clones of the child nodes in the containers. (The reason to use a span is semantic — the code we inject should probably be inline with the translation text.)

我们通过将innerHTML设置为空字符串来清除#target范围中的所有现有子节点 ,然后我们将子节点的克隆追加到容器中。 (使用span的原因是语义-我们注入的代码应该与翻译文本内联。)

Why cloning instead of moving the originals?

为什么要克隆而不是移动原件?

It’s because that we want to preserve the originals. This is also the rationale for hiding the #container div with display: none.

这是因为我们要保留原件。 这也是使用显示隐藏#container div的理由:none

Upon every language change we need to clone the originals again, and since those might contain translations of their own we need to wait for those to complete before cloning again.

每次更改语言后,我们都需要再次克隆原件,由于这些原件可能包含自己的译文,因此我们需要等待原件完成后再进行克隆。

HTML模板中的safeHtml管道如何处理? (What about the safeHtml pipe in the HTML template?)

Nothing fancy about that one, here’s the source:

没什么可想的,这是来源:

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';@Pipe({ name: 'safeHtml' })
export class SafeHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(value: any, ...args: any[]): any {
return this.sanitizer.bypassSecurityTrustHtml(value);
}
}

把它结语 (Let’s wrap it up)

Like I hinted earlier, I haven’t read up enough on web components to judge if this solution is warranted or not. But if you want something working fast with the tools you already use (Angular and Vanilla JS), then this solution might be a good fit for you.

就像我之前暗示的那样,我对Web组件的阅读不足,无法判断该解决方案是否必要。 但是,如果您希望使用已使用的工具(Angular和Vanilla JS)快速工作,那么此解决方案可能非常适合您。

翻译自: https://medium.com/swlh/how-to-embed-angular-components-inside-a-transloco-translation-string-e66600becef4

嵌入式c int转字符串

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值