【问题标题】:Angular Translate - Update translations executed via $tranlate.instant() in controller at runtimeAngular Translate - 在运行时更新通过控制​​器中的 $tranlate.instant() 执行的翻译
【发布时间】:2017-01-11 15:14:41
【问题描述】:

我正在使用 angular-translate 并尝试使用选择菜单 (on-change) 在运行时更改语言(不刷新页面)。但是,我正在处理的应用程序的前端从通过$translate.instant() 方法执行的翻译中获取其文本,因此当我通过$translate.use(langKey); 执行语言更改时,它对来自内部的文本没有影响控制器。

确实在通过 HTML 标记执行翻译时工作,使用指令或过滤器,但我正在处理一个相对较大的现有代码库并试图为自己节省大量的工作重构所有内容以将翻译移动到标记中。

我的控制器代码如下,我还设置了一个 Plunker 来演示这个问题(虽然用按钮而不是下拉菜单,但问题是一样的):http://plnkr.co/edit/ohzN9G

更新:我确实设法根据这个解决方案来完成这个工作:angular translate update translation table。但是,我的版本涉及为每个控制器使用 $watch,这在性能方面很昂贵,并且仍然需要在所有控制器上进行大量重构:http://plnkr.co/edit/TjEVeX

有没有更优雅的方法来达到同样的效果?

JS

var translationsEN = {
  HEADLINE: 'What an awesome module!',
  PARAGRAPH: 'Srsly!',
  PASSED_AS_TEXT: 'Hey there! I\'m passed as text value!',
  PASSED_AS_ATTRIBUTE: 'I\'m passed as attribute value, cool ha?',
  PASSED_AS_INTERPOLATION: 'Beginners! I\'m interpolated!',
  VARIABLE_REPLACEMENT: 'Hi {{name}}',
  MISSING_TRANSLATION: 'Oops! I have not been translated into German...',
  BUTTON_LANG_DE: 'German',
  BUTTON_LANG_EN: 'English'
};

var translationsDE= {
  HEADLINE: 'Was für ein großartiges Modul!',
  PARAGRAPH: 'Ernsthaft!',
  PASSED_AS_TEXT: 'Hey! Ich wurde als text übergeben!',
  PASSED_AS_ATTRIBUTE: 'Ich wurde als Attribut übergeben, cool oder?',
  PASSED_AS_INTERPOLATION: 'Anfänger! Ich bin interpoliert!',
  VARIABLE_REPLACEMENT: 'Hi {{name}}',
  // MISSING_TRANSLATION is ... missing :)
  BUTTON_LANG_DE: 'Deutsch',
  BUTTON_LANG_EN: 'Englisch'
};

var app = angular.module('myApp', ['pascalprecht.translate', ,'ngSanitize']);

app.config(['$translateProvider', 'translationHelperProvider', function ($translateProvider, translationHelperProvider) {
  // add translation tables
  $translateProvider.translations('en', translationsEN);
  $translateProvider.translations('de', translationsDE);
  $translateProvider.preferredLanguage('en');
  $translateProvider.fallbackLanguage('en');
  $translateProvider.useSanitizeValueStrategy('sanitize');

  translationHelperProvider.translations = $translateProvider.translations();

}]);

app.provider('translationHelper', function () {
    this.translations = {};

    this.$get = function () {
        return {
            translations: this.translations,
            preferredLanguage: this.preferredLanguage
        }
    };  
});

app.controller('Ctrl', ['$rootScope', '$translate', '$scope', 'translationHelper', function ($rootScope, $translate, $scope, translationHelper) {

  $scope.changeLanguage = function (langKey) {
    $translate.use(langKey).then(function () {
      $rootScope.globalLangKey = langKey;
    })

  }; 
}]);

app.controller('InnerCtrl', ['$rootScope', '$translate', '$scope', 'translationHelper', function ($rootScope, $translate, $scope, translationHelper) {
  $scope.translateMe = $translate.instant("HEADLINE");
 $rootScope.$watch('globalLangKey', function (newVal, oldVal) {
     if (newVal) {
       $scope.translateMe = translationHelper.translations[newVal]["HEADLINE"];
     }
 });
}]);

app.controller('AnotherInnerCtrl', ['$rootScope', '$translate', '$scope', 'translationHelper', function ($rootScope, $translate, $scope, translationHelper) {
  $scope.translateMeAParagraph = $translate.instant("PARAGRAPH");
 $rootScope.$watch('globalLangKey', function (newVal, oldVal) {
     if (newVal) {
       $scope.translateMeAParagraph = translationHelper.translations[newVal]["PARAGRAPH"];
     }
 });
}]);

标记

<!doctype html>
<html ng-app="myApp">
  <head>
    <script src="https://cdn.rawgit.com/SlexAxton/messageformat.js/v0.3.1/messageformat.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-animate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-cookies.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate/2.10.0/angular-translate.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-interpolation-messageformat/2.10.0/angular-translate-interpolation-messageformat.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-storage-cookie/2.10.0/angular-translate-storage-cookie.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular-sanitize.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-storage-local/2.10.0/angular-translate-storage-local.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-loader-url/2.10.0/angular-translate-loader-url.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-loader-static-files/2.10.0/angular-translate-loader-static-files.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-translate-handler-log/2.10.0/angular-translate-handler-log.js"></script>

    <script src="script.js"></script>
  </head>
  <body>

<div ng-controller="Ctrl">
  <p>{{ 'HEADLINE' | translate }}</p> 
  <p>{{ 'PARAGRAPH' | translate }}</p>


  <div ng-controller="InnerCtrl">
    <hr>
    <h2>This is the new nested controller I set up as a test</h2>
    <br>
    I used code from within the controller to translate this: 
    <br> {{translateMe}}
    <br>
    <br>
    This was done using <pre style="display: inline; font-weight: bold">translate="PASSED_AS_ATTRIBUTE</pre> approach<br>
    <span translate="PASSED_AS_ATTRIBUTE"></span></pre> <span translate="PASSED_AS_ATTRIBUTE"></span>
    <hr>

  </div>

    <div ng-controller="AnotherInnerCtrl">
      Here is another nested controller with the translation being executed from within the controller: <p>{{translateMeAParagraph}}</p>
      <hr>
    </div>



  <button ng-click="changeLanguage('de')" translate="BUTTON_LANG_DE"></button>
  <button ng-click="changeLanguage('en')" translate="BUTTON_LANG_EN"></button>
</div>


  </body>
</html>

【问题讨论】:

    标签: javascript angularjs angular-translate angular-controller


    【解决方案1】:

    如果你想使用 $translate.instant() ,你应该添加 $scope.$watch 作为触发其代码所需的值

    【讨论】:

    • 如果你看一下我的 JS 代码,你可以这样做 - 除非我误解了?谢谢,无论如何!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 2015-08-31
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    相关资源
    最近更新 更多