Как вы можете реализовать подход базы данных к интернационализации Angular?

Я прочитал руководство Angular i8n здесь: https://angular.io/guide/i18n

Мне нравятся понятия, используя разметку и подсказки в файле.

Мне не нравится, что текстовые ресурсы застряли в странном формате файла, которые легко перевести один раз, но очень сложно поддерживать внешними.

Есть ли простой способ использовать способ Angular поддерживает i8n, но заменять статические текстовые файлы на вызовы на базу данных - или даже что-то вроде json файла, сгенерированного базой данных?

Ответ 1

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

Когда речь заходит о переводах, мои бэкэнд и интерфейс отделены друг от друга. Переводы не отправляются в сборку angular или серверный пакет, а через вызов HTTP rest, который получил информацию из базовой базы данных. Все переводы загружаются при запуске, вносятся в структуру JSON и затем могут быть доставлены во внешний интерфейс, где ngx-translate заботится обо всем остальном. Здесь простой порядок событий для успешной загрузки перевода из базы данных и обеспечения их доступности для интерфейс.

  • безопасные переводы в базе данных
  • загружать переводы при запуске бэкэнда (или реализовать механизм перезагрузки, возможно через REST) ​​
  • преобразования карт в объекты JSON с ключом-значением пары
  • сделать объекты JSON доступными через REST api
  • frontend загружает объекты JSON через этот REST api
  • используйте объект JSON в angular с ngx-translate

преимущества

Позже я расскажу больше о том, как это может выглядеть, просто краткая заметка о том, какие преимущества приносит этот подход к базе данных-rest:

  • все переводы, хранящиеся в одном месте (одна таблица)
  • недостающие переводы для языка можно избежать (NULL-проверки)
  • можно выделить двойное распределение ключей (PRIMARY KEY)
  • возможно обновление переводов во время выполнения.
  • процесс перевода может быть проведен за пределами проекта (обновление файлов в структуре проекта не требуется)

Посмотрите, как это может быть достигнуто.

База данных

Переводы обычно состоят из простых пар ключей, основанных на файлах перевода, которые мне никогда не нравились. Поэтому вместо этого я сохраняю свои переводы в одной таблице с ключевым столбцом и столбцом перевода для каждого языка, который у меня есть, например, что-то вроде KEY | EN | FR | DE со значениями, такими как button.close | close | près | schließen. Ключ представляет тот же ключ, что и в обычном файле, но вместо отдельного файла на язык переводы сохраняются в одном столбце каждый.

Бэкэнд-сопоставление объектов JSON

Мне нравится загружать всю таблицу сразу, чтобы подготовить каждый язык для доставки интерфейса сразу. Обычно это можно сделать один раз при запуске бэкэнд, и результат можно сохранить в памяти, чтобы избежать многих вызовов базы данных. Таблица должна быть разделена на объекты JSON с ключом-значением для каждого столбца языка. Каждый результирующий объект языка затем содержит ключи базы данных в качестве своих ключей и переводы как их значения.

var EN = {
    ...
    "button.close": "close",
    ...
}
var FR = {
    ...
    "button.close": "près",
    ...
}
var DE = {
    ...
    "button.close": "schließen",
    ...
}

Это просто сопоставление между массивами и объектами, которое, в зависимости от языка сервера, обычно довольно просто (я могу поделиться своим кодом для node.js, если это необходимо). Результатом является список объектов языка JSON, каждый из которых имеет их перевод в виде пар ключ-значение, которые впоследствии могут быть доступны.

вызов HTTP rest

Перевод теперь в значительной степени в том же формате, что и обычный файл перевода (пары ключ-значение), просто хранится в памяти, а не в файле. С помощью простого HTTP-вызова api для определенного языка вы можете получить доступ к этому списку, взять объект перевода этого языка и отправить его прямо в интерфейс. Здесь приведен пример node.js.

translationRouter.route('/:lang').get(function (request, response) {
    // load translation key-value-pair object for requested language
    response.send(translationService.getTranslations(request.params.lang));
});

NGX-перевод

Способ ngx-translate работает довольно прямолинейно. Переводы загружаются в приложение angular, ключи перевода указаны в приложении, а затем динамически заменяются значениями перевода с предоставленного языка. Как указано другими, он поддерживает различные способы загрузки переводов, например, простые старые файлы переводов или самозагружаемые загрузчики, такие как загрузчики HTTP. Здесь простой HTTP-загрузчик, который загружает переводы через вызов REST (см. Выше).

import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import '../rxjs-operators';

export class TranslationLoader implements TranslateLoader {
    constructor(private http: HttpClient) { }

    getTranslation(lang: string): Observable<any> {
        return this.http.get("/api/translation/" + lang);
    }
}

Единственный трюк - указать этот загрузчик в качестве основного загрузчика, который можно сделать в app.module. Вот пример, который использует вышеупомянутый HTTP-загрузчик (и также работает для AOT).

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
export function HttpLoaderFactory(http: HttpClient) {
    return new TranslationLoader(http);
}
...
@NgModule({
    imports: [..., 
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: (HttpLoaderFactory),
                deps: [HttpClient]
            }
        }), ...]
})

Вместо запроса файла ngx-translate использует указанный TranslationLoader для получения своих пар ключ-значение, что является именно тем, предоставляя через наш отдых вызов. Очень просто. Для этого случая можно указать язык для загрузки, а также язык возврата в случае, если значение не найдено. Здесь приведен пример загрузки текстов по умолчанию и языков перевода.

// fallback language
this.translate.setDefaultLang('en');
// browser language
this.translate.use(this.translate.getBrowserLang());

Документация по ngx-translate довольно хороша, есть разные способы ее использования, например, через службу, директиву или канал, а также вы можете параметризовать переводы.


дополнительная информация

перезагрузка переводов

Как указано в списке преимуществ, вы также можете перезагружать переводы во время выполнения, что, вероятно, является более сложной задачей при наборе приложения для доставки. Вы можете просто предоставить HTTP-вызов для админов, который выполняет точно такую ​​же процедуру загрузки текста, что и при запуске. Таким образом, переводы могут быть перезагружены, переназначены и сохранены в памяти. Новые запросы страницы будут автоматически использовать перезагруженные объекты перевода.

изменение живого языка

Некоторые способы использования ngx-translate позволяют переключатели мгновенного перевода (например, через директиву). Таким образом, загрузка другого языка в angular (через простой вызов this.translate.use(lang)) мгновенно переключит показанные переводы без переустановки страницы или видимых компонентов, что на самом деле довольно аккуратно, но, к сожалению, не работает для всех способов использования.

пределы ngx-translate

Хотя ngx-translate действительно прост в использовании, он имеет ограничения. Одним из них является, например, использование директивы ngx-translate в сочетании с большинством директив angular, поскольку angular материал директивы (например, кнопки) будут создавать структуры поддерева, а ngx-translate только переводит ключи на первого ребенка (по крайней мере, я думаю, что это так). Так что здорово использовать, но иногда немного сложно.



Я думаю, что это так. В настоящее время я использую этот подход, и я очень доволен тем, как это получилось. Это небольшая работа, чтобы начать работу, но как только все будет кататься, это может быть очень полезно.

Ответ 2

Я могу предложить вам использовать ngx-translate (известная как ng2-translate before) библиотека, у которой есть лучший API, чем построена интернационализация -in в Angular... Таким образом, вы можете загружать переводы из статического json файла (может быть сгенерирован с помощью backend) или, например, добавьте toml-loader и сохраните ваши переводы, как в приведенном ниже примере (в файле assets/i18n/en.toml):

[homepage]
title = "Homepage title"
contact = "Contact"

[auth]
login = "Log in"
logout = "Log out"

[settings]
settings = "Settings"
body = "<b>HTML</b> is fine here"

и использовать его следующим образом:

<h2>{{'settings.settings' | translate}}</h2>
<p [innerHTML]="'settings.body' | translate"></p>
{{'auth.logout' | translate}}

Чтобы установить все это, вам понадобится в основном несколько строк кода:

import * as translation_en from 'toml-loader!../assets/i18n/en.toml';

@Injectable()
export class AppService {
    constructor(private translateService: TranslateService) {
        translateService.setDefaultLang('en');
        translateService.setTranslation('en', translation_en);
        translateService.use('en');
    }
}

Надеюсь, что это поможет!

Ответ 3

Я предлагаю вам использовать angular-l10n библиотеку. Это альтернатива open source для i18n для локализации angular. Он использует формат JSON и поддерживает также загрузку из сервисов. Вот также ссылка на документацию. angular -l10n configuration Найдите "Загрузка данных перевода" на странице, чтобы найти информацию о загрузке из веб-API.

Ответ 4

Пожалуйста, имейте в виду, что создатель ngx-translate теперь находится в основной команде Angular i18n, и как часть Angular 5.x работает над тем, чтобы сделать i18n намного лучше. Например. перевод, переключение времени выполнения в AOT и многое другое.

Смотрите здесь: https://github.com/angular/angular/issues/11405#issuecomment-343933617

Поэтому я бы рекомендовал придерживаться Angular готового i18n.

Для веб-сайта моей компании мы используем Text United для переводов, и это работает очень хорошо. Единственная проблема, которую мы имеем, заключается в том, что по умолчанию теги HTML оказываются в инструментах перевода. Наше решение:

  • с использованием XTB
  • В текстовом соединении, используя собственный XML-парсер. Исключить элементы ph.

Text United заплатил опционы, чтобы нанять переводчиков, чтобы сделать работу для вас на любом языке. Конечно, вы тоже можете это сделать. Каждый раз, когда вы просто загружаете исходный язык, и он соответствует уже переведенным элементам.

Ответ 5

Вы можете использовать ngx-translate, который является стандартной библиотекой интернационализации в Angular 2 +

Вы можете импортировать библиотеку и создать набор json файлов, которые содержат переводы, и поместить их в папку с ресурсами.

Затем вы можете ссылаться на него в HTML. скажем, например.

ru.json имеет,

"guest.first-name": "first Name",

где первый - это ключ, а второй - значение, которое должно отображаться. и вы можете ссылаться в html как,

<input  [label]="'guest.first-name' | translate" type="text" name="form_name" [(ngModel)]="firstName" required="required" ></input>

Ответ 6

В моем проекте у нас есть строковые литералы (требуемая интернационализация), которые хранятся в отдельном файле в формате x.y.z="Hello World". Мы разработали script для перевода этой строки в объект JSON как

x { y { z: { default: "Hello World" } } }

а затем мы использовали библиотеку "ng2-translate" для использования этого файла JSON для интернационализации в проекте angular 4.