Как использовать MatPaginatorIntl?

Я использую MatPaginator, и я пытаюсь понять, как перевести эти метки (документация недостаточно ясно об этом).

Я нашел эту статью, где показано, как это сделать, и я выполнил следующие шаги:

1 - Я создал файл с именем custom-paginator.ts и разместил там следующее:

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

export class CustomPaginator extends MatPaginatorIntl {
  constructor() {
    super();
    this.nextPageLabel = ' My new label for next page';
    this.previousPageLabel = ' My new label for previous page';
    this.itemsPerPageLabel = 'Task per screen';
  }
}

2 - В app.module.ts я поставлю:

@NgModule({
  // ...
  providers: [
    {
      provide: MatPaginatorIntl,
      useClass: CustomPaginator
    }
  ]
})
export class AppModule

Однако это просто ничего не меняет. Что мне не хватает?

Ответ 1

Вы можете сделать это следующим образом: Я предоставляю вам хорватские ярлыки:

customClass.ts

import {MatPaginatorIntl} from '@angular/material';
export class MatPaginatorIntlCro extends MatPaginatorIntl {
  itemsPerPageLabel = 'Stavki po stranici';
  nextPageLabel     = 'Slijedeća stranica';
  previousPageLabel = 'Prethodna stranica';

  getRangeLabel = function (page, pageSize, length) {
    if (length === 0 || pageSize === 0) {
      return '0 od ' + 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 + ' od ' + length;
  };

}

и AppModule.ts:

providers: [{ provide: MatPaginatorIntl, useClass: MatPaginatorIntlCro}],

Он отлично работает.

Кроме того, вам нужно импортировать в ваш appModule.ts как MatPaginatorIntl, так и MatPaginatorIntlCro

Ответ 2

Основываясь на коде Винко Вориха, я сделал paginator, работающий с ngx-translate, вот код:

import { Injectable } from '@angular/core';
import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from "@ngx-translate/core";

export class PaginatorIntlService extends MatPaginatorIntl {
  translate: TranslateService;
  itemsPerPageLabel = 'Items per page';
  nextPageLabel     = 'Next page';
  previousPageLabel = 'Previous page';
  getRangeLabel = function (page, pageSize, length) {
    const of = this.translate ? this.translate.instant('paginator.of') : 'of';
    if (length === 0 || pageSize === 0) {
      return '0 ' + 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 + ' ' + of + ' ' + length;
  };

  injectTranslateService(translate: TranslateService) {
    this.translate = translate;

    this.translate.onLangChange.subscribe(() => {
      this.translateLabels();
    });

    this.translateLabels();
  }

  translateLabels() {
    this.itemsPerPageLabel = this.translate.instant('paginator.items_per_page');
    this.nextPageLabel = this.translate.instant('paginator.next_page');
    this.previousPageLabel = this.translate.instant('paginator.previous_page');
  }

}

И тогда в вашем модуле провайдеры записываются:

{
  provide: MatPaginatorIntl,
  useFactory: (translate) => {
    const service = new PaginatorIntlService();
    service.injectTranslateService(translate);
    return service;
  },
  deps: [TranslateService]
}

Таким образом, вы можете хранить переводы в своем обычном файле i18n, и если ваше веб-приложение способно динамически менять локаль, paginator будет переводиться по требованию.

Ответ 3

в файле: matPaginatorIntlCroClass.ts

import {MatPaginatorIntl} from '@angular/material';
export class MatPaginatorIntlCro extends MatPaginatorIntl {
  itemsPerPageLabel = 'Items par page';
  nextPageLabel     = 'Page Prochaine';
  previousPageLabel = 'Page Précedente';
}

в файле: AppModule.ts:

import { MatPaginatorModule, MatPaginatorIntl} from '@angular/material';
import { MatPaginatorIntlCro } from './matPaginatorIntlCroClass'

@NgModule({
  imports: [],
  providers: [{ provide: MatPaginatorIntl, useClass: MatPaginatorIntlCro}],
  ..
})

Источник: https://material.angular.io/components/paginator/api

Ответ 4

Я сделал некоторые изменения, чтобы исправить конечный индекс, когда начальный индекс превышает длину списка. Я также добавляю перевод для первой и последней страницы. Это для @угловой/материал 5.2.4 нумерации страниц.

import { Injectable } from '@angular/core';
import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';

@Injectable()
export class MatPaginationIntlService extends MatPaginatorIntl {
  translate: TranslateService;
  firstPageLabel = 'First page';
  itemsPerPageLabel = 'Items per page';
  lastPageLabel = 'Last page';
  nextPageLabel = 'Next page';
  previousPageLabel = 'Previous page';

  getRangeLabel = (page: number, pageSize: number, length: number): string => {
    const of = this.translate ? this.translate.instant('mat-paginator-intl.of') : 'of';
    if (length === 0 || pageSize === 0) {
      return '0 ' + of + ' ' + length;
    }
    length = Math.max(length, 0);
    const startIndex = ((page * pageSize) > length) ?
      (Math.ceil(length / pageSize) - 1) * pageSize:
      page * pageSize;

    const endIndex = Math.min(startIndex + pageSize, length);
    return startIndex + 1 + ' - ' + endIndex + ' ' + of + ' ' + length;
  };

  injectTranslateService(translate: TranslateService) {
    this.translate = translate;

    this.translate.onLangChange.subscribe(() => {
      this.translateLabels();
    });

    this.translateLabels();
  }

  translateLabels() {
    this.firstPageLabel = this.translate.instant('mat-paginator-intl.first_page');
    this.itemsPerPageLabel = this.translate.instant('mat-paginator-intl.items_per_page');
    this.lastPageLabel = this.translate.instant('mat-paginator-intl.last_page');
    this.nextPageLabel = this.translate.instant('mat-paginator-intl.next_page');
    this.previousPageLabel = this.translate.instant('mat-paginator-intl.previous_page');
  }
}

Ответ 5

Чтобы обновить метку, вы можете вызвать событие change после смены метки:

translateLabels() {
    this.firstPageLabel = this.translate.instant('mat-paginator-intl.first_page');
    ...
    this.changes.next();
}

Ответ 6

Кроме того, вы можете использовать инъекционные сервисы, пометив Intl как инъекционный сам по себе. Смотрите пример (игнорируйте особенности DoneSubject и LocalizeService, поскольку они являются пользовательскими реализациями):

    import { Injectable, OnDestroy } from '@angular/core';
    import { MatPaginatorIntl } from '@angular/material';
    import { LocalizeService } from 'app/general';
    import { DoneSubject } from 'app/rx';
    import { takeUntil } from 'rxjs/operators';

    @Injectable()
    export class MatPaginatorIntlLoc extends MatPaginatorIntl implements OnDestroy {
      constructor(private readonly localizer: LocalizeService) {
        super();

        localizer.locale$.pipe(takeUntil(this.done$)).subscribe(() => {
          this.itemsPerPageLabel = localizer.translate('mat paginator label: items per page');
          this.nextPageLabel = localizer.translate('mat paginator label: next page');
          this.previousPageLabel = localizer.translate('mat paginator label: previous page');
          this.firstPageLabel = localizer.translate('mat paginator label: first page');
          this.lastPageLabel = localizer.translate('mat paginator label: last page');
        });
      }

      private readonly done$ = new DoneSubject();

      ngOnDestroy() { this.done$.done(); }

      getRangeLabel = (page: number, pageSize: number, length: number) => this.localizer
        .translate('mat paginator label: x of y', [
          length > 0 && pageSize > 0 ? (page * pageSize + 1) + ' - ' + Math.min((page + 1) * pageSize, Math.max(length, 0)) : 0,
          Math.max(length, 0),
        ]);
    }

И не забудьте указать это в своем модуле:

    providers: [
        ...
        { provide: MatPaginatorIntl, useClass: MatPaginatorIntlLoc },
        ...
      ]

Ответ 7

Вставьте MatPaginatorIntl в любое место вашего приложения, установите желаемые переводы и вызовите change.next(). Повторите при каждом изменении языка (например, подписавшись на onLangChange при использовании ngx-translate).

Ответ 8

У меня была та же проблема, и затем я изменил в app.module.ts в операторе импорта TranslateModule на TranslateModule.forRoot()

Так это выглядит так:

imports: [
    ...
    TranslateModule.forRoot()
    ...
]

Цитата с сайта NPM: "Статический метод forRoot - это соглашение, которое предоставляет и настраивает службы одновременно. Убедитесь, что этот метод вызывается только в корневом модуле приложения, чаще всего называемом AppModule. Этот метод позволяет вам настройте TranslateModule, указав загрузчик, парсер и/или обработчик отсутствующих переводов. "

Вот вся статья: https://www.npmjs.com/package/@ngx-translate/core

Чтение этого может помочь решить многие проблемы с TranslateModule!

Ответ 9

Если вы хотите, чтобы динамический языковой переключатель с ngx-translate работал для вас, вот решение, оно работает для меня.

мат-Paginator-i18n.service.ts

import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { Injectable } from '@angular/core';

const ITEMS_PER_PAGE = 'Items per page:';
const NEXT_PAGE = 'Next page';
const PREV_PAGE = 'Previous page';
const FIRST_PAGE = 'First page';
const LAST_PAGE = 'Last page';

@Injectable()
export class MatPaginatorI18nService extends MatPaginatorIntl {
public constructor(private translate: TranslateService) {
  super();

  this.translate.onLangChange.subscribe((e: Event) => {
    this.getAndInitTranslations();
  });

  this.getAndInitTranslations();
}

public getRangeLabel = (page: number, pageSize: number, length: number): string => {
  if (length === 0 || pageSize === 0) {
    return '0 / ${length}';
  }

  length = Math.max(length, 0);

  const startIndex: number = page * pageSize;
  const endIndex: number = startIndex < length
    ? Math.min(startIndex + pageSize, length)
    : startIndex + pageSize;

  return '${startIndex + 1} - ${endIndex} / ${length}';
};

public getAndInitTranslations(): void {
  this.translate.get([
    ITEMS_PER_PAGE,
    NEXT_PAGE,
    PREV_PAGE,
    FIRST_PAGE,
    LAST_PAGE,
  ])
    .subscribe((translation: any) => {
      this.itemsPerPageLabel = translation[ITEMS_PER_PAGE];
      this.nextPageLabel = translation[NEXT_PAGE];
      this.previousPageLabel = translation[PREV_PAGE];
      this.firstPageLabel = translation[FIRST_PAGE];
      this.lastPageLabel = translation[LAST_PAGE];

      this.changes.next();
    });
}
}

В вашем модуле AppModule

@NgModule({
  // ...
  providers: [
    {
      provide: MatPaginatorIntl,
      useClass: MatPaginatorI18nService,
    },
  ],
})
export class AppModule {
// ...

en.json и др.

{
  "Items per page:": "Items per page:",
  "Next page": "Next page",
  "Previous page": "Previous page",
  "First page": "First page",
  "Last page": "Last page",
}