$translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题 [英] Angular Translate async timing issue with $translateProvider.useStaticFilesLoader

查看:21
本文介绍了$translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用出色的 Angular Translate ($translate) 指令/服务来处理多种区域设置语言,并且由于我有多个区域设置文件,因此我使用了方便的 $translateProvider.useStaticFilesLoader 通过 localeAbbr.json 的结构加载我的翻译文件,例如 en.jsones.json 等......我构建了一个 Plunker 来显示我的开源项目,该项目通过 Git 原始文件使用语言环境(指向实际的 Github 存储库,这意味着不是 plunker 演示的本地).我的项目是作为指令和服务构建的,我制作了一个小 Plunker 来显示我的 JSON 文件加载时间问题.

所有这些都表明 $translateProvider.useStaticFilesLoader 可以asynchronous 工作,而我真的需要它是 synchronous 因为到时候plunker 运行,JSON 文件尚未解析,而我已经在我的消息中调用了 $translate.instant().

我有一个 Plunker 显示了这个问题.

这是我快速服务演示的一部分:

app.factory('validationService', ['$filter', '$translate', function ($filter, $translate) {var service = this;var validationSummary = [];var errorMessages = ['INVALID_ALPHA','INVALID_ALPHA_SPACE','INVALID_ALPHA_NUM','INVALID_BOOLEAN'];//var $translate = $filter('translate');for(var i=0, ln=errorMessages.length; i < ln; i++) {验证Summary.push({领域:我,消息:$translate.instant(errorMessages[i])});}//附加公共函数service.getValidationSummary = getValidationSummary;退货服务;//函数声明函数 getValidationSummary() {返回验证摘要;}}]);

$translateProvider 配置

app.config(['$translateProvider', function ($translateProvider) {$translateProvider.useStaticFilesLoader({前缀:'https://rawgit.com/ghiscoding/angular-validation/master/locales/validation/',后缀:'.json'});//在启动时加载英语 ('en') 表$translateProvider.preferredLanguage('en').fallbackLanguage('en');}]);

通过控制器调用我的服务:

app.controller("TestController", function($scope, validationService) {var vm = 这个;vm.displayValidationSummary = true;vm.validationSummary = validationService.getValidationSummary();});

最后是使用控制器的 HTML:

<button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="displayValidationSummary = false">&times;</button><h4><strong>{{'错误' |翻译 }}!</strong></h4><ul><li ng-repeat="vm.validationSummary 中的项目">{{item.field }}: {{item.message}}</li>

由于我使用的是 AngularJS 1.3+,我也发现 $translate 只被翻译一次,所以作者建议使用 translateFilter.$stateful = true;我试过了,但这似乎没有帮助.

这里又是 Plunker

我花了数周时间试图找到并编写各种解决方案,但我从来没有让它工作,看到我的原始翻译代码我真的很难过:(

请帮忙!!!

编辑
我意识到我的问题并未涵盖与我的问题相关的所有内容.除了翻译延迟问题之外,我还必须传递额外的参数,这是一个巨大的问题,将它们传递给翻译匿名函数.到承诺完成时,我的论点状态已经改变.例如:

$translate(validator.message).then(function(translation) {//仅在 $validationSummary 中记录无效消息addToValidationSummary(formElmObj,翻译);//错误显示如果(!isValid){updateErrorMsg(translation, isValid);}else if(!!formElmObj && formElmObj.isValid) {addToValidationSummary(formElmObj, '');}},功能(数据){抛出无法翻译"+数据;});

解决方案

我发现将额外参数传递给 Promise 的匿名函数的问题的答案是使用 Closures,这样,promise 之前和里面的变量都是相同的.所以我基本上必须将我的 $translate 调用包装到闭包中,如下所示:

(function(formElmObj, isValid, 验证器) {$translate(validator.message).then(function(translation) {message = message.trim();//仅在 $validationSummary 中记录无效消息addToValidationSummary(formElmObj, message);//错误显示如果(!isValid){updateErrorMsg(message, isValid);}else if(!!formElmObj && formElmObj.isValid) {addToValidationSummary(formElmObj, '');}},功能(数据){抛出无法翻译"+数据;});})(formElmObj, isValid, 验证器);

现在终于,我的变量是正确的并且保持那个时间点的值:)

I am using the excellent Angular Translate ($translate) directive/service to deal with multiple Locale Languages and since I have multiple locale files I use the convenient $translateProvider.useStaticFilesLoader to load my translation files through a structure of localeAbbr.json, for example en.json, es.json, etc... I built a Plunker to show my open source project and that project uses the locale through Git raw files (pointing to the actual Github repository, meaning not local to the plunker demo). My project is built as a Directive and a Service, I made a small Plunker to show my timing issue with the JSON file loading.

All that to say that it seems $translateProvider.useStaticFilesLoader works asynchronous while I would really need it to be synchronous because by the time the plunker runs, the JSON files are not yet parsed while I already called a $translate.instant() on my messages.

I have a Plunker showing the problem.

And here is part of my quick Service demo:

app.factory('validationService', ['$filter', '$translate', function ($filter, $translate) {
  var service = this;
  var validationSummary = [];
  var errorMessages = [
    'INVALID_ALPHA',
    'INVALID_ALPHA_SPACE',
    'INVALID_ALPHA_NUM',
    'INVALID_BOOLEAN'
  ];

  //var $translate = $filter('translate');

  for(var i=0, ln=errorMessages.length; i < ln; i++) {
    validationSummary.push({  
      field: i,
      message: $translate.instant(errorMessages[i])
    });
  }

  // attach public functions
  service.getValidationSummary = getValidationSummary;
  return service;

  // function declaration
  function getValidationSummary() {
    return validationSummary;
  }
}]);

The $translateProvider configuration

app.config(['$translateProvider', function ($translateProvider) {
  $translateProvider.useStaticFilesLoader({
    prefix: 'https://rawgit.com/ghiscoding/angular-validation/master/locales/validation/',
    suffix: '.json'
    });

    // load English ('en') table on startup
    $translateProvider.preferredLanguage('en').fallbackLanguage('en');
}]);

Call my Service through the Controller:

app.controller("TestController", function($scope, validationService) {
  var vm = this;
  vm.displayValidationSummary = true;

  vm.validationSummary = validationService.getValidationSummary();
});

and finally the HTML using the controller:

<div class="alert alert-danger alert-dismissable" ng-show="vm.displayValidationSummary">
  <button type="button" class="close" data-dismiss="alert" aria-hidden="true" ng-click="displayValidationSummary = false">&times;</button>
  <h4><strong>{{ 'ERRORS' | translate }}!</strong></h4>
  <ul>
      <li ng-repeat="item in vm.validationSummary">{{item.field }}: {{item.message}}</li>
  </ul>
</div>

Since I'm using AngularJS 1.3+, I also found that $translate only gets translated once, so the author suggest to use translateFilter.$stateful = true; and I tried but that doesn't seem to help.

Again here is the Plunker

I have been spending weeks on trying to find and code all kind of solution but I never got it to work and I'm really sad of seeing my raw translation code :(

Please Help!!!

EDIT
I realized that my question was not covering everything related to my problem. On top of the translation delay problem, I also have to pass extra arguments and that is a huge problem passing them to the translation anonymous function. By the time the promise is finished, the state of my arguments have already changed. For example:

$translate(validator.message).then(function(translation) {
    // only log the invalid message in the $validationSummary
    addToValidationSummary(formElmObj, translation);

    // error Display
    if(!isValid) {
      updateErrorMsg(translation, isValid);
    }else if(!!formElmObj && formElmObj.isValid) {
      addToValidationSummary(formElmObj, '');
    }
}, function(data) {
    throw 'Failed to translate' + data;
});

解决方案

I found out the answer to my problem of passing extra arguments to the anonymous function of the promise is to use Closures, in this way the variables are the same before the promise and inside it too. So I basically have to wrap my $translate call into the closure, something like the following:

(function(formElmObj, isValid, validator) {
    $translate(validator.message).then(function(translation) {
        message = message.trim();

        // only log the invalid message in the $validationSummary
        addToValidationSummary(formElmObj, message);

        // error Display
        if(!isValid) {
          updateErrorMsg(message, isValid);
        }else if(!!formElmObj && formElmObj.isValid) {
          addToValidationSummary(formElmObj, '');
        }
    }, function(data) {
        throw 'Failed to translate' + data;
    });
})(formElmObj, isValid, validator);

and now finally, my variables are correct and keep the value at that point in time :)

这篇关于$translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆