使用angular-translate实现国际化

最近在业余兼职中碰到网站有国际化,之前听说过,但确实没做过,经过几天网上查资料和摸索,最终实现了基于angular-translate的国际化。

要实现网站国际化,主要分为两部分,第一部分是html上静态数据的国际化,比如按钮的文本;第二部分就是接口返回数据的国际化。

我们先来分析第一部分的国际化。

静态

首先,编写前端静态文本的国际化文件,包含英语、日语和中文三个。

静态文本多语言编写

en.js

var LocaleEn = {
    home:"Home",
    about:"About Us",
    cooperation:"Cooperation",
    login:"Login",
    register:"Register"
}

ja.js

var LocaleJa = {
    home:"トップページ",
    about:"私たちについて",
    cooperation:"レストラン提携",
    login:"登録",
    register:"登記"
}

zh.js

var LocaleZh = {
    home:"首页",
    about:"关于我们",
    cooperation:"餐厅合作",
    login:"登录",
    register:"注册"
}

angular-translate初始化

$translateProvider
                .translations('en', LocaleEn)
                .translations('zh', LocaleZh)
                .translations('ja', LocaleJa)
                .preferredLanguage(Utils.getLanguage());
# Utils.getLanguage()主要是根据缓存语言或当前浏览器语言返回en、ja或者zh

静态文本展示

<a class="nav_link" href="">{{ 'home' | translate }}</a>

语言更换

$scope.changeLanguage = function () {
                Utils.setStorage("language", $scope.lang); # 缓存语言选择
                $translate.use($scope.lang);
}

经过如上处理,语言切换已经将页面静态文本根据对应的语言翻译正确了,接下来就需要处理接口数据中的国际化。

动态

通过上面的代码,要实现接口数据的国际化,需要在LocaleEn、LocaleZh、LocaleJa中增加相应的翻译对照。

笔者通过新增一个后端接口,将所有页面会用到的多语言文本对照返回,同时经过数据量的统计,因为主要是返回一些基础数据的多语言,对服务器和数据库的压力比较小。

当然,写这个接口前,你需要保证每个基础数据在库中包含有相应的多语言文本。

输入图片说明

接下来看看接口返回

后端接口

{
    "code": "200",
    "data": [
        {
            "en": "Sichuan Province",
            "id": "agentarea_name_8",
            "ja": "四川省",
            "zh": "四川省"
        },
        {
            "en": "Japan",
            "id": "agentarea_name_10",
            "ja": "日本",
            "zh": "日本"
        }
    ],
    "message": "success",
    "success": true
}

接口返回中主要涉及id和相应的多语言文本,id的生成规则为"类型_属性_实例id",下面需要更改angular-translate初始化,保证使用LoacleJa之前已经加载了接口返回的多语言文本。

加载后端多语言文本

Utils.initResourceTranslate(); # 增加加载多语言后端接口返回数据
            $translateProvider
                .translations('en', LocaleEn)
                .translations('zh', LocaleZh)
                .translations('ja', LocaleJa)
                .preferredLanguage(Utils.getLanguage());
initResourceTranslate: function () {
        console.log("document.domain;", document.domain)
        $.ajax({
            headers: {
                'tourcandy-browser-type': "web"
            },
            type: "GET",
            url: "/tourcandy/api/locale/translate",
            async: false, #将ajax调用修改为同步,保证正确的执行顺序
            success: function (data) {
                console.log("resource translate", data)
                if (data.success) {
                    for (var i = 0; i < data.data.length; i++) {
                        var tranlate = data.data[i];
                        LocaleZh[tranlate.id] = tranlate.zh;
                        LocaleEn[tranlate.id] = tranlate.en;
                        LocaleJa[tranlate.id] = tranlate.ja;
                    }
                }

            }
        });
    }

接下来就是如何使用后端多语言,要实现文本的正确翻译,就必须传入相应的id.

<a class="nav_link" href="">{{ 'home' | translate }}</a>

这种方式是没办法传入id的,因此要自定义filter。

自定义filter

App.filter('translateResource', ["$parse", "$translate",function ($parse, $translate) {
    var translateResourceFilter = function (translationId, interpolateParams, interpolation, forceLanguage) {
        console.log("translateResource filter", translationId, interpolateParams, interpolation, forceLanguage, angular.isObject(interpolateParams))
        if (!angular.isObject(interpolateParams)) {
            var ctx = this || {
                '__SCOPE_IS_NOT_AVAILABLE': 'More info at https://github.com/angular/angular.js/commit/8863b9d04c722b278fa93c5d66ad1e578ad6eb1f'
            };
            interpolateParams = $parse(interpolateParams)(ctx);
        }
        if (interpolateParams && interpolateParams._id) {
            translationId += interpolateParams._id
        }
        return $translate.instant(translationId, interpolateParams, interpolation, forceLanguage);
    };
    if ($translate.statefulFilter()) {
        translateResourceFilter.$stateful = true;
    }
    return translateResourceFilter;
}]);

基本是将translate这个filter代码拷贝过来,增加

 if (interpolateParams && interpolateParams._id) {
            translationId += interpolateParams._id
        }

使用

<a class="condition_menu" ng-repeat="city in citys">{{ 'agentarea_name_' | translateResource:{_id:city.id} }}</a>

猜你喜欢

转载自my.oschina.net/sannychan/blog/1816378