AngularJS的多语言支持

在某些情况下,需要提供多语言支持。 有时,在您正在构建的应用程序中提供对不同语言的支持,并为您的用户提供以不同习惯用法查看内容的可能性是一个好主意。 在本教程中,我将向您展示如何向任何AngularJS应用程序添加多语言支持。

我们将使用AngularJS构建一个需要多种语言支持的多语言支持的单页面应用程序,以便用户无需刷新页面即可立即在两种语言之间切换。 在这种情况下,我们需要对应用程序做更多的事情,包括翻译其文本,立即在不同语言之间切换或更改布局方向(从RTL到LTR)。

本文开发的所有代码都可以在GitHub上找到

环境设定

在我要向您展示的示例中,我将使用BowerGulp使我们的开发环境尽可能自动化和灵活。 如果尚未将它们安装在系统上,或者如果您从未在开发工作流程中使用过它们,则强烈建议您安装并开始更多地了解它们。 这是为此有用的文章列表:

首先,让我们通过在项目目录内的命令行中运行bower init来设置Bower,我们将其称为multilingualwithangularbower init将以交互方式创建一个名为bower.json的清单文件,该清单文件将包含有关项目的一些信息以及以前安装的前端依赖项的列表。

下一步是安装所需的初始软件包。

bower install angular angular-translate --save

让我们设置Gulp并安装这些基本软件包。 首先,我们需要运行命令npm init并遵循一些简单的步骤来创建package.json文件,其中将包含有关项目以及如何管理Node.js模块的一些信息。

接下来,我们将在项目中安装Gulp:

npm install gulp --save-dev

我们还需要JavaScript和Sass以及其他自动化工具的一些Gulp依赖项。

npm install gulp-sass gulp-uglify gulp-concat run-sequence browser-sync --save-dev

此时,我们必须在项目目录中创建一个空的gulpfile.js配置文件。 它将用于定义我们的Gulp任务,例如JavaScript和Sass。 您可以在我的GitHub存储库中查看完整的配置文件

在JavaScript任务中,我们将在/js目录中添加两个文件angularangular-translate ,以及主JavaScript文件。 然后,我们将它们连接在一起,并使用一个名为Uglify的 Node.js库来压缩和减小文件的大小。

'use strict';

var gulp         = require('gulp');
var sass         = require('gulp-sass');
var concat       = require('gulp-concat');
var uglify       = require('gulp-uglify');
var runSequence  = require('run-sequence');
var browserSync  = require('browser-sync');

gulp.task('js', function(){
  return gulp.src([
    './bower_components/angular/angular.js',
    './bower_components/angular-translate/angular-translate.js',

    './js/app.js'])
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'))
});

gulp.task('serve', function() {
  browserSync({
    server: {
      baseDir: "./"
    }
  });
});

gulp.task('build', [], function() {
  runSequence('js');
});

gulp.task('default', ['build'], function() {});

完成后,我们可以运行之前创建的gulp build任务。 它会运行js任务,然后生成一个/js/app.min.js文件,该文件将包含在一个简单的HTML文件中。

<!DOCTYPE HTML>
<html>
<head>
  <title>Multilingual AngularJS</title>
  <meta charset="utf-8">
</head>

<body>
  <script src="js/app.min.js"></script>
</body>
</html>

要在localhost环境中打开项目,请运行gulp serve ,然后将自动打开一个指向localhost:3000的浏览器选项卡。

使用Angular-Translate添加翻译

完成这些第一个配置任务后,就该迈出一步,为应用程序文本添加翻译支持了。 我们将阿拉伯语和英语作为主要语言。 就语法,语法和书写方向而言,它们是完全不同的语言(从右至左的阿拉伯语和从左至右的英语)。

angular-translate是一个AngularJS模块,可用于翻译文本。 它提供了许多有趣的功能,例如过滤器,指令和i18n数据的异步加载。

首先,让我们设置AngularJS并使用angular-translate对其进行配置

// js/app.js

var app = angular.module('Multilingual', ['pascalprecht.translate']);

app.config(['$translateProvider', function($translateProvider) {

  $translateProvider
  .translations('ar', {
    'HELLO': 'مرحبا'
  })
  .translations('en', {
    'HELLO': 'Hello'
  })
  .preferredLanguage('ar');

}]);

然后,让我们稍微修改一下HMTL:

<html ng-app="Multilingual">

然后从命令行运行gulp build来构建JavaScript文件中的新更改。 在前面的代码片段中,我们有:

  • 创建了一个名为Multilingual的Angular模块。
  • 作为pascalprecht.translateangular-translate模块作为依赖项注入到我们的应用程序中。
  • .config()方法中注入了$translateProvider
  • 使用.translations()方法并以诸如enar类的语言键作为第一个参数,以不同的语言注册翻译表。
  • 使用.preferredLanguage()方法设置首选语言(这很重要,因为我们使用了不止一种语言,因此我们可以教您在首次加载时进行哪种angular-translate )。

让我们看一个使用translate滤镜进行angular-translate的示例

<h2>{{ 'HELLO' | translate }}</h2>

视图中的过滤器太多,导致翻译指示文档中描述的手表表达式过多。 实现它的更好,更快的方法是使用translate指令。 使用该指令的另一个原因是,用户可能会看到原始的{{ 'HELLO' | translate }} 在AngularJS加载模板之前,先{{ 'HELLO' | translate }}

我们可以使用伪指令的方法是将翻译ID传递为translate伪指令的属性值。

<h2 translate="HELLO"></h2>

有时我们可能需要知道我们是否错过了一些翻译ID。 angular-translate-handler-log提供了一个很好的方法,称为useMissingTranslationHandlerLog() ,可以帮助我们解决此问题,该方法会将警告信息记录在控制台中,以useMissingTranslationHandlerLog()缺少的翻译ID。 要使用它,我们必须先安装它。 您可以使用Bower做到这一点:

bower install angular-translate-handler-log --save

然后,更新JavaScript Gulp任务:

gulp.task('js', function(){
  return gulp.src([
    './bower_components/angular/angular.js',
    './bower_components/angular-translate/angular-translate.js',

    // New file
    './bower_components/angular-translate-handler-log/angular-translate-handler-log.js',

    './js/app.js'])
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'));
});

最后,直接在$translateProvider上使用此方法运行gulp build如下所示:

$translateProvider
  .translations('ar', {
    'HELLO': 'مرحبا'
  })
  .translations('en', {
    'HELLO': 'Hello'
  })
  .preferredLanguage('ar')
  .useMissingTranslationHandlerLog();

如果我们错过了HELLO的翻译,由于这种方法,我们将收到一条警告消息,内容为“不存在HELLO的翻译”。

异步加载翻译文件

除了直接在.config()方法中添加不同语言的翻译数据外,还有另一种方法可以异步和延迟地加载它们。 实际上, 有多种方法可以完成此任务 ,但是在本教程中,我们将仅使用angular-translate-loader-static-files扩展名。

首先,我们需要使用Bower安装扩展:

bower install angular-translate-loader-static-files --save

安装完成后,我们需要使用扩展文件路径更新Gulp任务,然后运行gulp build

gulp.task('js', function(){
  return gulp.src([
    './bower_components/angular/angular.js',
    './bower_components/angular-translate/angular-translate.js',
    './bower_components/angular-translate-handler-log/angular-translate-handler-log.js',

    // New file
    'bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',

    './js/app.js'])
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'));
});

此时,我们需要创建/translations目录并添加语言翻译文件。 结构将如下所示:

translations
├── ar.json
└── en.json

ar.json文件中,编写以下报告的内容:

{
  "HELLO": "مرحبا",
  "BUTTON_LANG_AR": "العربية",
  "BUTTON_LANG_EN": "الإنجليزية",
  "WELCOME_MESSAGE": "مرحباً في موقع AngularJS المتعدد اللغات"
}

相反,在en.json文件中保存以下内容:

{
  "HELLO": "Hello",
  "BUTTON_LANG_AR": "Arabic",
  "BUTTON_LANG_EN": "English",
  "WELCOME_MESSAGE": "Welcome to the AngularJS multilingual site"
}

现在,我们可以使用useStaticFilesLoader方法通过useStaticFilesLoader方法告诉您使用特定模式加载哪些语言文件,进行angular-translate

prefix - specifies file prefix
suffix - specifies file suffix

以下是JavaScript文件的更改方式:

// js/app.js

app.config(['$translateProvider', function($translateProvider) {

  $translateProvider
  .useStaticFilesLoader({
    prefix: '/translations/',
    suffix: '.json'
  })
  .preferredLanguage('ar')
  .useMissingTranslationHandlerLog();
}]);

如果要向文件添加前缀,可以使用前缀(在这种情况下为locale- )重命名每个文件:

translations
├── locale-ar.json
└── locale-en.json

通过应用此更改,我们必须如下更新app.js文件:

// js/app.js

app.config(['$translateProvider', function($translateProvider) {

  $translateProvider
  .useStaticFilesLoader({
    prefix: '/translations/locale-',
    suffix: '.json'
  })
  .preferredLanguage('ar')
  .useMissingTranslationHandlerLog()
}]);

在这里, angular-translate将我们的代码连接为{{prefix}}{{langKey}}{{suffix}} ,然后加载例如/translations/locale-en.json文件。

在不同语言之间切换

到目前为止,我们已经看到了如何使用两种语言的文本翻译。 但是,我们仍然无法在运行时从浏览器切换到其他语言。 为此,我们需要为每种语言添加一个按钮以从中切换。

<div ng-controller="LanguageSwitchController">
  <button ng-show="lang == 'en'" ng-click="changeLanguage('ar')" translate="BUTTON_LANG_AR"></button>
  <button ng-show="lang == 'ar'" ng-click="changeLanguage('en')" translate="BUTTON_LANG_EN"></button>
</div>

我们还可以创建一些$rootScope属性,并在我们的HTML代码上使用它们,以便在首次加载时设置初始布局方向和lang属性,并在以后每次更改语言时将其绑定。

// js/app.js

app.run(['$rootScope', function($rootScope) {
  $rootScope.lang = 'en';

  $rootScope.default_float = 'left';
  $rootScope.opposite_float = 'right';

  $rootScope.default_direction = 'ltr';
  $rootScope.opposite_direction = 'rtl';
}])

angular-translate提供了一种方便的方法,称为use ,它use一个参数并根据传递的参数为我们设置语言。 此外,我们将收听$translateChangeSuccess事件,该事件在翻译更改成功后就会触发,以确保语言已更改。 然后,我们可以根据所选语言修改$rootScope属性:

// js/app.js

app.controller('LanguageSwitchController', ['$scope', '$rootScope', '$translate',
  function($scope, $rootScope, $translate) {
    $scope.changeLanguage = function(langKey) {
      $translate.use(langKey);
    };

    $rootScope.$on('$translateChangeSuccess', function(event, data) {
      var language = data.language;

      $rootScope.lang = language;

      $rootScope.default_direction = language === 'ar' ? 'rtl' : 'ltr';
      $rootScope.opposite_direction = language === 'ar' ? 'ltr' : 'rtl';

      $rootScope.default_float = language === 'ar' ? 'right' : 'left';
      $rootScope.opposite_float = language === 'ar' ? 'left' : 'right';
    });
}]);

并将以下更改应用于标记:

<html lang="{{ lang }}" ng-app="Multilingual">

在我的标题为使用Helper类进行DRY和Scale CSS的文章中 ,您可以看到另一个示例,这些示例在HTML中将这些方向属性用作Helper类:

<div class="text-{{ default_float }}"></div>

记住语言

至此,我们已经建立了切换语言功能,并且可以更改语言以使用我们最喜欢的语言。 下一步是让应用程序记住我们选择的语言,因此,下次启动它时,我们不必再次切换到该语言。

我们将使用浏览器localStorage教会应用程序记住该语言,以存储所选语言,并且为此目的,我们将使用angular-translate-storage-local扩展名。 您可以想象,下一步是安装它。 我们将与Bower一起做:

bower install angular-translate-storage-local --save

运行此命令,我们还将安装angular-cookiesangular-translate-storage-cookie作为依赖项。 安装完成后,我们需要使用运行gulp build的新文件来更新Gulp任务:

gulp.task('js', function(){
  return gulp.src([
    './bower_components/angular/angular.js',
    './bower_components/angular-translate/angular-translate.js',
    './bower_components/angular-translate-handler-log/angular-translate-handler-log.js',
    'bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',

    // New files
    './bower_components/angular-cookies/angular-cookies.js',
    './bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.js',
    './bower_components/angular-translate-storage-local/angular-translate-storage-local.js',

    './js/app.js'])
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./js'));
});

使用此代码后,接下来的步骤是:

  • 添加ngCookies作为依赖项。
  • 告诉$translateProvider通过useLocalStorage()使用localStorage

我们需要进行以下操作:

var app = angular.module('Multilingual', [
  'pascalprecht.translate',
  'ngCookies'
  ]);

app.config(['$translateProvider', function($translateProvider) {
  $translateProvider
  .useStaticFilesLoader({
    prefix: '/translations/',
    suffix: '.json'
  })
  .preferredLanguage('ar')
  .useLocalStorage()
  .useMissingTranslationHandlerLog()
}]);

angular-translate将存储我们由preferredLanguage()使用键NG_TRANSLATE_LANG_KEY设置的初始语言。 它将在浏览器localStorage中将语言分配为其值,然后在每次用户切换语言时对其进行更新。 当用户打开应用程序时, angular-translate将从localStorage检索

本地存储

使用布局方向

我们已经到达演示部分。 如果您使用书写方向相同的两种语言(例如英语和法语),则配置已完成。 如果语言方向之一是RTL,而另一方向是LTR,则我们需要做一些额外的工作来调整某些布局方案。

假设这是LTR语言(英语)的CSS代码:

.media-image { padding-right: 1rem; }

对于RTL语言,以上代码应镜像为padding-left而不是padding-right

.media-image { padding-left: 1rem; }

但是,这根本不是一个好习惯,因为它很耗时,并且涉及到代码重复:

[lang='ar'] .media-image {
  padding-right: 0;
  padding-left: 1rem;
}

为了解决这个问题,我们需要编写一些CSS代码,并以有效,自动化和动态的方式支持RTL语言和LTR。 使用这种方法,我们不必重复或覆盖CSS规则。 我鼓励您阅读我的文章“ 使用Sass和Grunt管理RTL CSS”,以了解有关此技术以及如何在项目中使用它的更多信息。

在本教程中,我们将使用Gulp来实现它,并添加一个使用ltr-app.scssrtl-app.scss的Sass任务。 除了导入其中的特定于方向的变量外,我们还将导入主Sass文件:

gulp.task('sass', function () {
  return gulp.src(['./sass/ltr-app.scss', './sass/rtl-app.scss'])
  .pipe(sass())
  .pipe(gulp.dest('./css'));
});

// Update the build task with sass
gulp.task('build', [], function() {
  runSequence('js', 'sass');
});

sass/ltr-app.scss文件应如下所示:

// LTR language directions

$default-float:       left;
$opposite-float:      right;

$default-direction:   ltr;
$opposite-direction:  rtl;

@import 'style';

这是sass/rtl-app.scss的代码:

// RTL language directions

$default-float:       right;
$opposite-float:      left;

$default-direction:   rtl;
$opposite-direction:  ltr;

@import 'style';

最后,这是sass/style.scss的示例:

body { direction: $default-direction; }

.column { float: $default-float; }

.media-image { padding-#{$opposite-float}: 1rem; }

使用所有这些代码之后,您可以运行gulp build ,Sass任务将生成两个文件。 css/rtl-app.css将具有下面列出的代码:

/* css/rtl-app.css */

body { direction: rtl; }

.column { float: right; }

.media-image { padding-left: 1rem; }

css/ltr-app.css文件将包含以下报告的内容:

/* css/ltr-app.css */
body { direction: ltr; }

.column { float: left; }

.media-image { padding-right: 1rem; }

下一步也是最后一步,就是根据当前语言动态使用这些生成的文件。 我们将使用$rootScopedefault_direction属性在首次加载期间设置方向,然后在更改语言时将其绑定。

<link ng-href="css/{{ default_direction }}-app.css" rel="stylesheet">

结论

如我们所见,在涉及AngularJS转换时,使用angular-translate是可行的方法。 它提供了许多方便的过滤器,指令和有趣的工具。 我们以许多不同的方式介绍了翻译过程,并探讨了如何在两种语言之间切换。 我们还讨论了如何在用户浏览器存储中存储选定的语言,以及如何与CSS配合使用以使表示层对语言指示的响应速度更快。

希望您喜欢本教程。 我已经为本文创建了GitHub存储库, 您可以在此处查看代码 。 请在下面的部分中随意分享您的评论。

From: https://www.sitepoint.com/multilingual-support-for-angularjs/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值