如何在角4翻译垫-分页器?

你有任何想法,我如何翻译“项目每页”在角度的 mat-paginator标签?mat-paginator是材料设计中的一个元素。

62194 次浏览

您可以使用 MatPaginatorIntl进行此操作。威尔 · 豪厄尔的一个例子,不再工作,所以这里是一个更新版本(荷兰语)和一步一步的指导。

  1. MatPaginatorIntl@angular/material导入到应用程序中。
  2. 为您的区域设置创建一个新的分页器文件(在本例中我使用的是 Dutch) ,并在 main.ts文件中导入: import { getDutchPaginatorIntl } from './app/dutch-paginator-intl';
  3. main.ts文件内的 Paginator 设置一个 provider,这样它就可以获取本地文件的翻译(而不是默认语言为英语) :
providers: [
{ provide: MatPaginatorIntl, useValue: getDutchPaginatorIntl() }
]
  1. 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;

StackBlitz 上的示例,以分页器翻译文件作为起点。


2018年6月-更新至角度6.x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 6.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2019年6月-更新至角8.x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 8.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2020年2月-更新至角度9. x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 9.x,以适应最新版本的框架。软件包版本已经更改。主要改变是从角材料进口的方式。您不能再从材质根导入。您需要指定来自模块(material/paginator)本身的导入:

import { MatPaginatorModule, MatPaginatorIntl } from '@angular/material/paginator';

2020年6月-更新至角度10.x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 10.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2020年12月-更新至角11. x
这次更新的 < strong > StackBlitz 的示例 升级到了 Angular 11.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2021年5月-更新至角度12.x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 12.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2022年1月-更新至角13. x
这次更新的 < strong > StackBlitz 的示例 升级到了 Angular 13.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2022年6月-更新至角14.x
这次更新的 < strong > StackBlitz 的示例 升级到了 Angular 14.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。


2022年11月-更新至角度15.x
这个更新的 < strong > StackBlitz 的示例 升级到了 Angular 15.x,以适应最新版本的框架。只有包发生了变化,分页器内部没有任何变化。

对于一个快速而肮脏的解决方案,请使用 this.paginator. _ intl 属性。

在我的 ...component.ts中,我有:

@ViewChild(MatPaginator) paginator: MatPaginator;


ngOnInit() {
...
this.paginator._intl.itemsPerPageLabel = 'My translation for items per page.';
...
}

根据 翻译接受的答案修改解决方案(角度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中配置 翻译:

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 { }
this.dataSource.paginator._intl.itemsPerPageLabel = "Your string here";

这个工作在最新的角8 + 材料8;

你可以黑进 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;
});

对于角度9.0.0,如果使用 i18n 包,可以这样做

要求:

创建一个名为 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.modle.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>

按照当前的 Angular Materials 文档(10.2.0)修改标签和显示的文本,创建 MatPaginatorIntl 的新实例,并将其包含在自定义提供程序中。必须导入 MatPaginatorModule (无论如何都需要它来显示分页器组件)

import { MatPaginatorModule } from '@angular/material/paginator';

在你的组件中(在你使用分页器的地方) ,你可以按照以下方式使用它:

 constructor(private paginator: MatPaginatorIntl) {
paginator.itemsPerPageLabel = 'Your custom text goes here';
}

更改 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;
}

我以 费里斯的回答为基础,他以 罗伊的回答为基础。

为了解决动态语言切换的问题,我的工厂方法使用 TranslateServicestream()方法(而不是 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"
}
}

使用 ngx 翻译的简单解决方案。

@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;
}

@ 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;
}

如果要动态更改语言,可以输入以下代码:

    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}`;
}

它在编辑对象 matPaginatorIntl 之后导入‘ changes.next () ;’。

如果您使用 变态并且需要翻译 mat-paginator字符串,请将这个类型脚本类添加到您的项目中:

import { Injectable } from '@angular/core';
import { TranslocoService } from '@ngneat/transloco';
import { MatPaginatorIntl } from '@angular/material/paginator';


@Injectable()
export class CustomMatPaginatorIntl extends MatPaginatorIntl  {


ofLabel: string = 'of';


constructor(private _translate: TranslocoService) {
super();
this._translate.langChanges$.subscribe((lang) => {
this.getAndInitTranslations();
});
this.getAndInitTranslations();
}


getAndInitTranslations(): void {
this._translate.selectTranslate('paginator.itemsPerPageLabel').subscribe((value) => {
this.itemsPerPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.nextPageLabel').subscribe((value) => {
this.nextPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.previousPageLabel').subscribe((value) => {
this.previousPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.firstPageLabel').subscribe((value) => {
this.firstPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.lastPageLabel').subscribe((value) => {
this.lastPageLabel = value;
this.changes.next();
});
this._translate.selectTranslate('paginator.ofLabel').subscribe((value) => {
this.ofLabel = value;
this.changes.next();
});
}


getRangeLabel = (
page: number,
pageSize: number,
length: number,
): string => {
if (length === 0 || pageSize === 0) {
return `0 ${this.ofLabel} ${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} ${
this.ofLabel
} ${length}`;
};
}

然后在你的 Module中这样称呼它:

@NgModule({
imports: [
...
TranslocoModule,
],
providers: [
{ provide: MatPaginatorIntl, useClass: CustomMatPaginatorIntl } // >> add this line
]
})

ES 国际化的本地解决方案(只需更改标签的值和您所使用的语言中相应的标签的值) ,超直接且不触及 app.molde:

import { MatPaginatorIntl } from '@angular/material/paginator';


...


constructor(
...
private paginator: MatPaginatorIntl
) {
paginator.nextPageLabel = 'Siguiente';
paginator.previousPageLabel = 'Anterior';
paginator.lastPageLabel = 'Última Página';
paginator.firstPageLabel = 'Primera Página';
paginator.itemsPerPageLabel = 'Registros por Página';
paginator.getRangeLabel = (page: number, pageSize: number, length: number) => {
if (length == 0 || pageSize == 0) { return `0 de ${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} de ${length}`;
};
}