如何使用angular-translate自定义加载器动态地动态决定转换表的URL?

时间:2016-10-24 11:55:06

标签: angularjs angular-translate

如何使用$translateProvider

动态决定转换表的URL

目前,我们关注 - [https://angular-translate.github.io/docs/#/guide/12_asynchronous-loading](asynchronous loading)在我们的一个应用程序中。我们已经使用了这个方法将近2年。但是,现在我们面临着一个不同的任务。我们必须根据逻辑来决定我们的翻译文件的URL。逻辑如下, 如果文件存在于给定的location中,则通过它解析翻译,或者回退到default location

我当前的环境

  • 版本的angular-translate - 2.4.2 with angular-translate-partial-loader - 2.4.2
  • 版本角度 - 1.5

App的结构

|-- mod 1
|   |-- de_de.json
|   |-- en_us.json
|   |-- es_es.json
|   `-- zh_tw.json
|-- mod 2
|   |-- de_de.json
...Followed by corresponding translation files.

代码结构:

的application.js

myapp.config(['$translateProvider', '$translatePartialLoaderProvider',function ( $translateProvider, $translatePartialLoaderProvider ) {
    $translateProvider.useLoader( '$translatePartialLoader', {
        urlTemplate: 'i18n/{part}/{lang}.json'
    } );
    $translateProvider.preferredLanguage( "en_us" );
    $translateProvider.fallbackLanguage( "en_us" );
}]);
........
myapp.run( function ( $rootScope, $translate, editableOptions ) {
    $rootScope.$on( '$translatePartialLoaderStructureChanged', function () {
        $translate.refresh();
    } );
    editableOptions.theme = 'bs3';
} );

controller1.js

myapp.controller1("Controller1",function($scope, ...,.., $translate, $translatePartialLoader,$rootScope) {
    /*@ngInject*/
    $translatePartialLoader.addPart('login');
    $translatePartialLoader.addPart('home');
.......
 $scope.setLanguage = function(lang) {
     $translate.use(lang);
    }

到目前为止一直很好。现在我们要更改application.js的逻辑以生成解析URL的转换表。我们必须检查是否有particular_part/in_particular_language的转换表。

预期的结构和行为

|-- mod 1
|  |-- Custom
|  |  |-- de_de.json
|  |  |........followed by all custom translations for mod1 i.e, $translatePartialLoader.addPart('mod1') 
|  |-- en_us.json
|  |-- es_es.json
|   `-- zh_tw.json
|-- mod 2
|   |-- de_de.json

在新结构中,我们将在每个模块下有自定义目录,如果在自定义中存在零件/模块的翻译文件,则使用part/Custom/lang_key.json else fall back to part/lang_key.json(as before)解析

我们如何通过ng-translate实现这一目标?

我采用的方法是编写custom loader。但options的{​​{1}}仅将参数限制为由$translatePartialLoader传递的lang_key。如何我们是否可以将$translate.use(lang_key)传递给mod1进入$translatePartialLoader.addPart('mod1')。我们无法将其传递给customLoader,因为我们在用户登录时只调用$translate.use('lang_key/mod1')一次。

如果我们可以从$translate.use('land_key')调用中获取添加的模块,则传递到我们的$translatePartialLoader('mod1')然后根据逻辑我们可以相应地解析翻译。目前,我仍然坚持如何将添加的部分添加到{ {1}}因为它是由控制器(控制器1 ..)加载的。是否有一种方法或自定义服务应该被编写以将添加的部分/模块...添加到我们的customLoader中,如果是的话,你可以吗?指导我或帮助我使用相关代码或者我们是否必须更改应用程序的整个结构 - 如果更改结构将有所帮助,那么结构应该是什么?

感谢。

1 个答案:

答案 0 :(得分:0)

用于获取用户选择的部件或模块的自定义服务。

myapp.factory('fetchLanguagePart', function ($q, $timeout) {
/*@ngInject*/
var languageService = {};
languageService.languagePart = ['defaultmod1', 'defaultmod2'];  //Translation tables from these parts are always required.

languageService.getLanguagePart = function () {
    var deferred = $q.defer();
    var url = purl();
    var part = grabbedPart;

    //Logic for part deciding.

    languageService.languagePart = part;
    return part;
}
return languageService;
})

配置

myapp.config(['$translateProvider', '$translatePartialLoaderProvider', function ($translateProvider, $translatePartialLoaderProvider) {

    //Default language loader.

    // $translateProvider.useLoader( '$translatePartialLoader', {
    //  urlTemplate: 'i18n/{part}/{lang}.json'
    // } );

    //Custom language loader for angular-translate.

    $translateProvider.useLoader('customLanguageTemplateLoader', {})
    $translateProvider.forceAsyncReload(true);
    $translateProvider.useSanitizeValueStrategy();
}]);

CustomLoader它获取默认模块转换表和自定义模块转换表并合并它们并将其传递给angular-translate。

myapp.factory('customLanguageTemplateLoader', function ($q, $http, fetchLanguagePart, $timeout) {
/*@ngInject*/
return function (options) {

    var getCustomLanguagePath = function (part) {
        return 'i18n/' + part + '/Custom/' + options.key + '.json';
    }
    var getFallBackLanguagePath = function (part) {
        return 'i18n/' + part + '/' + options.key + '.json';
    }
    //To fetch default part translations and then merge with custom part translations
    var fetchPartTranslations = function () {
        var deferred = $q.defer();
        var responses;
        var part = fetchLanguagePart.getLanguagePart();
        var customLanguageUrl = getCustomLanguagePath(part);
        var fallbackLanguageUrl = getFallBackLanguagePath(part);
        $http.get(fallbackLanguageUrl).success(function (fallbackResult) {
            responses = fallbackResult;
            $http.get(customLanguageUrl).success(function (customResult) {
                var updatedResult = angular.extend(responses, customResult);
                angular.extend(responses, customResult);
                deferred.resolve(responses);
            }).error(function (error) {
                deferred.resolve(responses);
            })
        })
        return deferred.promise;
    }
    var deferred = $q.defer();
    var part = fetchLanguagePart.getLanguagePart();
    var customLanguageUrl = getCustomLanguagePath(part);
    var fallbackLanguageUrl = getFallBackLanguagePath(part);
    var responses;

    //To fetch default module translation tables merge it with custom module translations and then merge the result of the two with  part translations.

    $http.get(getFallBackLanguagePath('home')).success(function (fallBackHome) {
        responses = fallBackHome;
        $http.get(getCustomLanguagePath('home')).success(function (customHomeResult) {
            var updatedResult = angular.extend(responses, customHomeResult);
            fetchPartTranslations().then(function (partTranslations) {
                angular.extend(responses, partTranslations);
                angular.extend(responses, customHomeResult);
                deferred.resolve(responses);
            });
        }).error(function (error) {
            fetchPartTranslations().then(function (partTranslations) {
                angular.extend(responses, partTranslations);
                deferred.resolve(responses);
            });
        })
    })
    return deferred.promise;
}
})