javascript - $translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题

标签 javascript angularjs angularjs-directive angular-services angular-translate

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

综上所述,$translateProvider.useStaticFilesLoader 似乎可以异步,而我真的需要它是同步,因为到时候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++) {
    validationSummary.push({  
      field: i,
      message: $translate.instant(errorMessages[i])
    });
  }

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

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

$translateProvider 配置

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');
}]);

通过 Controller 调用我的服务:

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

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

最后是使用 Controller 的 HTML:

<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>

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

这里又是Plunker

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

请帮忙!!!

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

$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;
});

最佳答案

在使用 AngularJS 或 JavaScript 时,您确实需要接受异步范例。为了减少处理异步代码的麻烦,您可以使用 Promises。 Angular 为您提供了一项名为 $q 的服务,它可以为您完成繁重的工作

https://docs.angularjs.org/api/ng/service/$q

让人们思考 Promises 可能需要时间,但从长远来看非常值得付出努力。

本质上,您需要对 validationService 执行的操作是使用 $translate 的 promise api,它将根据提供的 key 为您提供所需的翻译。这归结为你向 $translate 请求所有你希望获得翻译的 translationId,当所有的都被获取后,你用你的消息填充 validationSummary 数组。

app.factory('validationService', ['$q', '$translate', function ($q, $translate) {

  var translationsPromises = [], 
    validationSummary = [],
    errorMessages = [
      'INVALID_ALPHA',
      'INVALID_ALPHA_SPACE',
      'INVALID_ALPHA_NUM',
      'INVALID_BOOLEAN'
    ];


  angular.forEach(errorMessages, function(val, key) {
    translationsPromises.push($translate(val));
  });

  $q.all(translationsPromises)
    .then(function(translations) {
      angular.forEach(translations, function(val, key) {
        validationSummary.push({
          filed: key,
          message: val
        });
      });
    })
    .catch(function (err) {
      console.error('Failed to translate error messages for validation summary', err);  
    });

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

  return {
    getValidationSummary: getValidationSummary
  };

}]);

我已经 fork 你的 plunker 并修改它以包含上面的示例

http://plnkr.co/edit/7DCwvY9jloXwfetKtcDA?p=preview

另一个观察结果是您在 HTML 中使用了翻译过滤器。请注意,如果你有一个大的 DOM,这可能会被证明是昂贵的,因为 Angular 会调用翻译每个摘要上的每个键。一种可以考虑的方法是为您的虚拟机提供一个标签对象,并使用 $filter 服务在 Controller 实例化时填充它们。

关于javascript - $translateProvider.useStaticFilesLoader 的 Angular Translate 异步计时问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29551379/

相关文章:

javascript - 在 MongoDB 的 Node.js 中链接多个 promise 函数

javascript - 以多种形式获取所有选定复选框的值

angularjs - es6 扩展运算符到构造函数的自动类绑定(bind)

javascript - JavaScript Controller 中的 Angular JS 过滤

javascript - 我如何在 angularjs 指令中获取已编译的(?)字符串

AngularJS 数据绑定(bind)类型

javascript - 部署 Express 并使用路由前缀进行 react

javascript - PageDown 通过 ScriptEngine 错误解析 Markdown

css - Font Awesome 图标不响应 ng-click

支持路由的 AngularJS UI Bootstrap 选项卡