0

我正在使用角度翻譯並試圖在運行時(不刷新頁面)使用選擇菜單(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"]; 
    } 
}); 
}]); 

$ MARKUP

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

回答

0

,如果你想使用$ translate.instant(),你應該添加$範圍。留意是否是值需要觸發它的代碼

+0

你可以這樣做,如果你看我的JS代碼 - 除非我誤會了嗎?無論如何謝謝! – doronorenstein