如何在 Angular 4 中翻译 mat-paginator?
Posted
技术标签:
【中文标题】如何在 Angular 4 中翻译 mat-paginator?【英文标题】:How to translate mat-paginator in Angular 4? 【发布时间】:2018-05-15 13:50:37 【问题描述】:您知道如何翻译 Angular 的 mat-paginator
标记中的“每页项目数”吗? mat-paginator
是 Material Design 中的一个元素。
【问题讨论】:
【参考方案1】:您可以为此使用MatPaginatorIntl
。 Will Showell made 一个不再有效的示例,所以这里有一个更新版本(带有荷兰语)和分步指南。
-
将
MatPaginatorIntl
从@angular/material
导入您的应用程序。
为您的语言环境创建一个新的分页器文件(在本例中我使用荷兰语)并将其导入:import getDutchPaginatorIntl from './app/dutch-paginator-intl';
in main.ts
文件
在 main.ts
文件中为 Paginator 设置一个 provider
,以便它采用本地文件的翻译(而不是英语作为默认语言):
providers: [
provide: MatPaginatorIntl, useValue: getDutchPaginatorIntl()
]
-
在您的 paginator-intl 文件中,为可以翻译的字符串设置标签并导出这些标签。该文件最重要的部分(有关详细信息,请参阅示例):
paginatorIntl.itemsPerPageLabel = 'Items per pagina:';
paginatorIntl.firstPageLabel = 'Eerste pagina';
paginatorIntl.previousPageLabel = 'Vorige pagina';
paginatorIntl.nextPageLabel = 'Volgende pagina';
paginatorIntl.lastPageLabel = 'Laatste pagina';
paginatorIntl.getRangeLabel = dutchRangeLabel;
Example on StackBlitz 以分页器翻译文件为起点。
2018 年 6 月 - 更新到 Angular 6.x 这个更新的Example on StackBlitz 升级到 Angular 6.x 以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。
2019 年 6 月 - 更新到 Angular 8.x 这个更新的Example on StackBlitz 升级到 Angular 8.x 以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。
2020 年 2 月 - 更新到 Angular 9.x
这个更新的Example on StackBlitz 升级到 Angular 9.x 以适应最新版本的框架。软件包版本已更改。主要变化是从 Angular Material 导入的方式。您不能再从 Material 根目录导入。您需要从模块 (material/paginator
) 本身指定导入:
import MatPaginatorModule, MatPaginatorIntl from '@angular/material/paginator';
2020 年 6 月 - 更新到 Angular 10.x 这个更新的Example on StackBlitz 升级到 Angular 10.x 以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。
2020 年 12 月 - 更新到 Angular 11.x 这个更新的Example on StackBlitz 升级到 Angular 11.x 以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。
2021 年 5 月 - 更新到 Angular 12.x 这个更新的Example on StackBlitz 升级到 Angular 12.x 以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。
【讨论】:
对于一些翻译字符串来说有点复杂,但它可以工作,谢谢 国际化对我来说非常有效,但它仍然以大写显示工具提示的值?我不知道为什么会这样? 是的,但是您如何将它与 TranslateService 一起使用,这可能是最常见的用例 我相信你打错了;最新更新中的 19.x 应该是 10.x。 年复一年,从 6 到 10 角,你应该得到超过 123 个赞:D【参考方案2】:要获得快速而肮脏的解决方案,请使用 this.paginator._intl 属性。
在我的...component.ts
我有:
@ViewChild(MatPaginator) paginator: MatPaginator;
ngOnInit()
...
this.paginator._intl.itemsPerPageLabel = 'My translation for items per page.';
...
【讨论】:
在使用这种方法时,我们如何翻译'of'? "31-60 0f 20000"this.paginator._intl.getRangeLabel = (page: number, pageSize: number, length: number) => if (length == 0 || pageSize == 0) return
0 din $length; length = Math.max(length, 0); const startIndex = page * pageSize; const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize; return
$startIndex + 1 - $endIndex of $length; ;
这将在您在使用分页器的所有其他组件中触发后被调用【参考方案3】:
根据@ngx-translate 接受的答案修改解决方案(使用 Angular 6):
@NgModule(
imports: [...],
providers: [
provide: MatPaginatorIntl, deps: [TranslateService],
useFactory: (translateService: TranslateService) => new PaginatorI18n(translateService).getPaginatorIntl()
]
)
export class CoreModule
还有PaginatorI18n
:
import MatPaginatorIntl from '@angular/material';
import TranslateService from '@ngx-translate/core';
export class PaginatorI18n
constructor(private readonly translate: TranslateService)
getPaginatorIntl(): MatPaginatorIntl
const paginatorIntl = new MatPaginatorIntl();
paginatorIntl.itemsPerPageLabel = this.translate.instant('ITEMS_PER_PAGE_LABEL');
paginatorIntl.nextPageLabel = this.translate.instant('NEXT_PAGE_LABEL');
paginatorIntl.previousPageLabel = this.translate.instant('PREVIOUS_PAGE_LABEL');
paginatorIntl.firstPageLabel = this.translate.instant('FIRST_PAGE_LABEL');
paginatorIntl.lastPageLabel = this.translate.instant('LAST_PAGE_LABEL');
paginatorIntl.getRangeLabel = this.getRangeLabel.bind(this);
return paginatorIntl;
private getRangeLabel(page: number, pageSize: number, length: number): string
if (length === 0 || pageSize === 0)
return this.translate.instant('RANGE_PAGE_LABEL_1', length );
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return this.translate.instant('RANGE_PAGE_LABEL_2', startIndex: startIndex + 1, endIndex, length );
和cz.json
"ITEMS_PER_PAGE_LABEL": "Počet řádků:",
"NEXT_PAGE_LABEL": "Další stránka",
"PREVIOUS_PAGE_LABEL": "Předchozí stránka",
"FIRST_PAGE_LABEL": "První stránka",
"LAST_PAGE_LABEL": "Poslední stránka",
"RANGE_PAGE_LABEL_1": "0 z length",
"RANGE_PAGE_LABEL_2": "startIndex - endIndex z length"
在app.module.ts
中配置ngx-translate:
import TranslateLoader, TranslateModule, TranslateService from '@ngx-translate/core';
const httpLoaderFactory = (http: HttpClient) => new TranslateHttpLoader(http, './assets/i18n/', '.json');
@NgModule(
imports: [
TranslateModule.forRoot(
loader: provide: TranslateLoader, useFactory: httpLoaderFactory, deps: [HttpClient]
)
],
providers: [ provide: LOCALE_ID, useValue: 'cs' ],
bootstrap: [AppComponent]
)
export class AppModule
【讨论】:
唯一提出动态翻译的解决方案 - 这是您应该想要的方式。这应该是公认的答案。 @MichalStepan 我同意,通过我多次尝试让它在 StackBlitz 上运行,但他们还不接受静态资产。见github.com/stackblitz/core/issues/577 @puntanet 我已经更新了答案,请看最底部。然后cz.json
位于src/assets/i18n
下。
这个答案很好,但是当语言改变时它不会更新翻译。与其在getPaginatorIntl
中返回对象,不如让类扩展MatPaginatorIntl
并返回对象本身。还需要调用this.changes.next()
来刷新现有表。查看其他帖子***.com/questions/46869616/…
为了解释语言切换,我使用了this.translate.stream()
,它在每次语言更改时报告一个新值。【参考方案4】:
this.dataSource.paginator._intl.itemsPerPageLabel = "Your string here";
这在最新的 angular8 + material8 中有效;
【讨论】:
【参考方案5】:您可以破解到MatPaginator._intl
并使用ngx-translate
将您的字符串放在那里。
forkJoin(
itemsPerPageLabel: this.translate.get('paginator.itemsPerPageLabel'),
nextPageLabel: this.translate.get('paginator.nextPageLabel'),
previousPageLabel: this.translate.get('paginator.previousPageLabel'),
firstPageLabel: this.translate.get('paginator.firstPageLabel'),
lastPageLabel: this.translate.get('paginator.lastPageLabel'),
).subscribe(values =>
this.paginator._intl.itemsPerPageLabel = values.itemsPerPageLabel;
this.paginator._intl.nextPageLabel = values.nextPageLabel;
this.paginator._intl.previousPageLabel = values.previousPageLabel;
this.paginator._intl.firstPageLabel = values.firstPageLabel;
this.paginator._intl.lastPageLabel = values.lastPageLabel;
// 1 – 10 of 100
// https://github.com/angular/components/blob/master/src/material/paginator/paginator-intl.ts#L41
this.paginator._intl.getRangeLabel = (page: number, pageSize: number, length: number): string =>
length = Math.max(length, 0);
const startIndex = page * pageSize;
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return this.translate.instant('paginator.getRangeLabel',
startIndex: startIndex + 1,
endIndex,
length,
);
;
// Otherwise, the paginator won't be shown as translated.
this.dataSource.paginator = this.paginator;
);
【讨论】:
【参考方案6】:对于 Angular 9.0.0,如果你使用的是 i18n 包,你可以这样做
要求:ng add @angular/localization
创建一个名为 my-paginator-intl.ts 的文件
import MatPaginatorIntl from '@angular/material/paginator'
const matRangeLabelIntl = (page: number, pageSize: number, length: number) =>
if (length === 0 || pageSize === 0)
return $localize`:@@paginator.zeroRange:0 in $length`
length = Math.max(length, 0)
const startIndex = page * pageSize
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize
return $localize`:@@paginator.rangeOfLabel:$startIndex + 1 - $endIndex in $length`
export function MyPaginatorIntl()
const paginatorIntl = new MatPaginatorIntl()
paginatorIntl.itemsPerPageLabel = $localize`:@@paginator.displayPerPage:Items per page`
paginatorIntl.nextPageLabel = $localize`:@@paginator.nextPage:Next page`
paginatorIntl.previousPageLabel = $localize`:@@paginator.prevPage:Prev page`
paginatorIntl.getRangeLabel = matRangeLabelIntl
return paginatorIntl
导入到 app.modudle.ts
import MatPaginatorIntl from '@angular/material/paginator'
import MyPaginatorIntl from './shared/paginator-int/my-paginator-intl'
@NgModule(
providers: [
provide: MatPaginatorIntl, useValue: MyPaginatorIntl() ,
]
)
将以下内容复制到您的语言 xlf 文件中
<trans-unit id="paginator.zeroRange">
<source>0 of <x id="PH" /></source>
<target>0 trong <x id="PH" /></target>
</trans-unit>
<trans-unit id="paginator.rangeOfLabel">
<source><x id="PH" /> - <x id="PH_1" /> of <x id="PH_2" /></source>
<target><x id="PH" /> - <x id="PH_1" /> trong <x id="PH_2" /></target>
</trans-unit>
<trans-unit id="paginator.displayPerPage">
<source>Items per page</source>
<target>Hiển thị/Trang</target>
</trans-unit>
<trans-unit id="paginator.nextPage">
<source>Next page</source>
<target>Trang kế</target>
</trans-unit>
<trans-unit id="paginator.prevPage">
<source>Prev page</source>
<target>Trang trước</target>
</trans-unit>
【讨论】:
【参考方案7】:按照当前的 Angular Material 文档 (10.2.0) 修改显示的标签和文本,创建 MatPaginatorIntl 的新实例并将其包含在自定义提供程序中。您必须导入 MatPaginatorModule(无论如何您都需要它来显示分页器组件)
import MatPaginatorModule from '@angular/material/paginator';
在您的组件中(您使用分页器的地方)您可以通过以下方式使用它:
constructor(private paginator: MatPaginatorIntl)
paginator.itemsPerPageLabel = 'Your custom text goes here';
【讨论】:
【参考方案8】:更改 MatPaginator 的所有标签的简洁解决方案。
const rangeLabel: string = 'із';
const itemsPerPageLabel: string = 'Елементiв на сторiнцi:';
const firstPageLabel: string = 'Перша сторінка';
const lastPageLabel: string = 'Остання сторінка';
const previousPageLabel: string = 'Попередня сторінка';
const nextPageLabel: string = 'Наступна сторінка';
const getRangeLabel: (page: number, pageSize: number, length: number) => string = (
page: number,
pageSize: number,
length: number
): string =>
return new MatPaginatorIntl().getRangeLabel(page, pageSize, length).replace(/[a-z]+/i, rangeLabel);
;
export function getPaginatorIntl(): MatPaginatorIntl
const paginatorIntl: MatPaginatorIntl = new MatPaginatorIntl();
paginatorIntl.itemsPerPageLabel = itemsPerPageLabel;
paginatorIntl.firstPageLabel = firstPageLabel;
paginatorIntl.lastPageLabel = lastPageLabel;
paginatorIntl.previousPageLabel = previousPageLabel;
paginatorIntl.nextPageLabel = nextPageLabel;
paginatorIntl.getRangeLabel = getRangeLabel;
return paginatorIntl;
【讨论】:
【参考方案9】:我以Felix' answers 为基础,他以Roy's answer 为基础。
考虑到动态语言切换,我的工厂方法使用TranslateService
的stream()
方法(而不是instance()
),该方法返回一个每次设置语言时触发的可观察对象。我还打电话给分页器的change.next()
强制重绘。
TranslateService
能够返回词汇的“字典”。使用 JSON 文件中的正确键,Object.assign()
可以完成大部分工作。
最后,我没有重新实现分页器的getRangeLabel()
。相反,我采用旧值并将出现的“of”替换为翻译文本。
public getPaginatorIntl(): MatPaginatorIntl
const paginatorIntl = new MatPaginatorIntl();
this.translation.stream('paginator.paginatorIntl').subscribe(dict =>
Object.assign(paginatorIntl, dict);
paginatorIntl.changes.next();
);
const originalGetRangeLabel = paginatorIntl.getRangeLabel;
paginatorIntl.getRangeLabel = (page: number, size: number, len: number) =>
return originalGetRangeLabel(page, size, len)
.replace('of', this.translation.instant('paginator.of'));
;
return paginatorIntl;
这里以fr.json
为例。
"paginator":
"paginatorIntl" :
"itemsPerPageLabel": "Items par page",
"nextPageLabel": "Page suivante",
"previousPageLabel": "Page précédente",
"firstPageLabel": "Première page",
"lastPageLabel": "Dernière page"
,
"of": "de"
【讨论】:
【参考方案10】:使用 ngx-translate 的简单解决方案。
@ViewChild(MatPaginator, static: true ) paginator: MatPaginator;
constructor(private translate: TranslateService)
ngOnInit()
this.translatePaginator();
async translatePaginator()
const label = await this.translate.get('COMMON.ItemsPerPageLabel').toPromise();
this.paginator._intl.itemsPerPageLabel = label;
【讨论】:
这是一个断章取义的 sn-p。没有上下文,没有完整的类定义,也没有如何使用它的示例。【参考方案11】:@Felix 答案的另一个版本,但在这里您可以直接在函数中注入您的服务,而无需创建或实例化一个类:
在app.module.ts
添加您的提供商:
providers: [
YourCustomService,
provide: MatPaginatorIntl, useFactory: getPaginatorI18n, deps: [YourCustomService]
]
使用您的函数创建一个新的 ts 文件(例如 paginator-i18n.ts
):
import MatPaginatorIntl from '@angular/material/paginator';
// This is the word that shows up in the range label
let paginPerRng = '';
const i18nRangeLabel = (page: number, pageSize: number, length: number) =>
if (length == 0 || pageSize == 0)
return `0 $paginPerRng $length`;
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ?
Math.min(startIndex + pageSize, length) :
startIndex + pageSize;
return `$startIndex + 1 - $endIndex $paginPerRng $length`;
;
export function getPaginatorI18n(YourCustomService: customService)
const paginatorIntl = new MatPaginatorIntl();
// Call the localization methods in your service
paginatorIntl.itemsPerPageLabel = customService.getResource(...);
paginatorIntl.nextPageLabel = customService.getResource(...);
paginatorIntl.previousPageLabel = customService.getResource(...);
paginatorIntl.firstPageLabel = customService.getResource(...);
paginatorIntl.lastPageLabel = customService.getResource(...);
// We localize the word that shows up in the range label before calling the RangeLabel constant
paginPerRng = customService.getResource(...);
paginatorIntl.getRangeLabel = i18nRangeLabel;
return paginatorIntl;
【讨论】:
【参考方案12】:如果你想动态改变语言,你可以输入这个代码:
this.translate.onLangChange.subscribe(() =>
this.getPaginatorIntl(matPaginatorIntl);
);
private getPaginatorIntl(matPaginatorIntl: MatPaginatorIntl): void
matPaginatorIntl.itemsPerPageLabel = this.translate.instant('PAGINATOR.ITEM');
matPaginatorIntl.nextPageLabel = this.translate.instant('PAGINATOR.NEXT_PAGE');
matPaginatorIntl.previousPageLabel = this.translate.instant('PAGINATOR.PREVIOUS_PAGE');
matPaginatorIntl.firstPageLabel = this.translate.instant('PAGINATOR.FIRST_PAGE');
matPaginatorIntl.lastPageLabel = this.translate.instant('PAGINATOR.LAST_PAGE');
matPaginatorIntl.getRangeLabel = this.getRangeLabel.bind(this);
matPaginatorIntl.changes.next();
private getRangeLabel(page: number, pageSize: number, length: number): string
if (length === 0 || pageSize === 0)
return `0 $this.translate.instant('PAGINATOR.OF') $ length `;
length = Math.max(length, 0);
const startIndex = page * pageSize;
// If the start index exceeds the list length, do not try and fix the end index to the end.
const endIndex = startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize;
return `$startIndex + 1 - $endIndex $this.translate.instant('PAGINATOR.OF') $length`;
它是 import insert 'changes.next();'对象 matPaginatorIntl 编辑后。
【讨论】:
以上是关于如何在 Angular 4 中翻译 mat-paginator?的主要内容,如果未能解决你的问题,请参考以下文章
Angular 5 - 在 TypeScript 中翻译字符串
如何用管道翻译 Ionic/Angular 中 *ngFor 循环的返回