繁体   English   中英

如何在 Angular 4 中翻译 mat-paginator?

[英]How to translate mat-paginator in Angular 4?

您有什么想法如何翻译 Angular 的mat-paginator标签中的“每页项目数”吗? mat-paginator是 Material Design 中的一个元素。

您可以为此使用MatPaginatorIntl Will Howell 做了一个不再有效的例子,所以这里有一个更新版本(带有荷兰语)和分步指南。

  1. MatPaginatorIntl@angular/material导入到您的应用程序中。
  2. 为您的语言环境创建一个新的分页器文件(在此示例中,我使用荷兰语)并导入该文件: import { getDutchPaginatorIntl } from './app/dutch-paginator-intl'; main.ts文件中
  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 月 - 更新到 Angular 6.x
StackBlitz 上的这个更新示例已升级到 Angular 6.x,以适应最新版本的框架。 只有包发生了变化,分页器内部没有任何变化。


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


2020 年 2 月 - 更新到 Angular 9.x
StackBlitz 上的这个更新示例已升级到 Angular 9.x,以适应最新版本的框架。 软件包版本已更改。 主要变化是从 Angular Material 导入的方式。 您不能再从 Material 根目录导入。 您需要从模块( material/paginator )本身指定导入:

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

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


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


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


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


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

基于@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 { }

要获得快速而肮脏的解决方案,请使用 this.paginator._intl 属性。

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

@ViewChild(MatPaginator) paginator: MatPaginator;

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

对于 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.module.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>

你可以破解你的方式进入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;
});

我建立在Felix 的答案之上,他建立在Roy 的答案之上。

为了考虑动态语言切换,我的工厂方法使用TranslateServicestream()方法(而不是instance() ),该方法返回一个每次设置语言时触发的 observable。 我还调用了分页器的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"
    }
}
this.dataSource.paginator._intl.itemsPerPageLabel = "Your string here";

这适用于最新的 angular8 + material8;

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

按照当前的 Angular Material 文档 (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;
}

使用 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; }

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

    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 的编辑之后。

如果您使用transloco并且需要翻译mat-paginator字符串,请将此 typescript 类添加到您的项目中:

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.moulde:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM