使用angular-translate指令回退到另一个translationId

时间:2015-08-18 16:51:56

标签: angularjs angularjs-directive angular-translate

angular-translate 2.7.2,AngularJS 1.4.2

我有要求(不要问......)对于我网站上每个可翻译的文本片段,实际上有两个候选翻译,其中一个是通过在translationId中添加前缀而得到的。

翻译示例:

greeting => "hi"
abc.greeting => "yo"

abc.是我的前缀。如果可以翻译abc.greeting,则应显示其翻译,否则返回到translationId greeting(如果可用),如果翻译不存在:放弃,处理丢失的翻译。

我想将此行为包装成一个指令,以便我仍然可以方便地使用它:

<p my-translate="greeting"></p>

根据translateIds的存在产生<p>yo</p><p>hi</p>。我在我的指令中提出了这个代码,它实际上包含了$translate

function translateWithFallback(translationId, translationValues, element, prefix) {

  function successHandler(translation) {
    element.html(translation);
  }

  function failureHandler(translationId) {
    element.html("???" + translationId + "???");
  }

  var prefixedTranslationId = prefix + translationId;
  $translate(prefixedTranslationId, translationValues).then(successHandler, function() {
    $translate(translationId, translationValues).then(successHandler, failureHandler);
  });
}

很快我意识到与 angular-translate 指令相比,这个解决方案缺乏:它没有注意到语言选择(我想我需要听$translateChangeSuccess)并且没有设置观察者更改translationId和translationValues。 angular-translate 指令已经完成所有并以有效的方式https://stackoverflow.com/a/23866441

所以我的问题是:如何扩展或重复使用translate指令,但是有关translateIds的后备?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我终于找到了修改 angular-translate 的方法,同时仍能使用其指令和过滤器。本质上,我用自己的函数替换了$translate$provide允许我装饰 $translate,然后由 angular-translate 的其他工具使用。

module.config([ "$provide", function($provide) {
        $provide.decorator('$translate', [ "$delegate", function($delegate) {

                function translate(translationId, tValues, iId, dTText, myPrefix) {
                       // fallback logic which makes use of $delegate
                }
                translate.preferredLanguage = $delegate.preferredLanguage;
                translate.cloakClassName = $delegate.cloakClassName;
                translate.fallbackLanguage = $delegate.fallbackLanguage;
                translate.useFallbackLanguage = $delegate.useFallbackLanguage;
                translate.proposedLanguage = $delegate.proposedLanguage;
                translate.storage = $delegate.storage;
                translate.use = $delegate.use;
                translate.storageKey = $delegate.storageKey;
                translate.isPostCompilingEnabled = $delegate.isPostCompilingEnabled;
                translate.isForceAsyncReloadEnabled = $delegate.isForceAsyncReloadEnabled;
                translate.refresh = $delegate.refresh;
                translate.instant = $delegate.instant;
                translate.versionInfo = $delegate.versionInfo;
                translate.loaderCache = $delegate.loaderCache;
                translate.directivePriority = $delegate.directivePriority;
                translate.statefulFilter = $delegate.statefulFilter;
                return translate;
        } ]);
} ]);

还要复制一堆属性;否则我的translate函数不能替代$translate。仍然看起来有点hacky,但这是我能想到的最好的解决方案。至少没有其他更改(甚至自己的指令或过滤器),只需要这个配置块。

答案 1 :(得分:0)

据我了解,您需要检查翻译才能存在 首先想到的是:

//it's return translate with prefix, if exist
//and  translate without prefix or original value;
$scope.isExist = function(value){
    //value = 'greeting';
    var tr1 = $filter('translate')(value);
    var tr2 = $filter('translate')('abc.' + value);

    return tr2 !== 'abc.' + value ? tr2 : tr1;
};

并且已经可以使用:

$rootScope.$on('$translateChangeSuccess', function(){
  //do something with $scope.isExist(); like:
  $scope.somethingValue = $scope.isExist(somethingValue);
});

小心翻译数据,它不适用于以下数据:

abc.greeting => "abc.greeting"
abc.value=> "abc.value"
//but it is unlikely, that You could have tr. like 'abc.Hello';

我希望这会对你有所帮助;
抱歉我的英文;