nde*_*ker 118 javascript angularjs angular-translate
我在AngularJS应用程序中使用angular-translate for i18n.
对于每个应用程序视图,都有一个专用控制器.在下面的控制器中,我将值设置为页面标题.
<h1>{{ pageTitle }}</h1>
Run Code Online (Sandbox Code Playgroud)
.controller('FirstPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
$scope.pageTitle = $filter('translate')('HELLO_WORLD');
}])
.controller('SecondPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
$scope.pageTitle = 'Second page title';
}])
Run Code Online (Sandbox Code Playgroud)
我正在使用angular-translate-loader-url扩展名加载翻译文件.
在初始页面加载时,将显示翻译键,而不是该键的翻译.翻译是Hello, World!
,但我看到了HELLO_WORLD
.
我第二次去页面,一切都很好,并显示翻译版本.
我假设问题与控制器分配值时可能尚未加载转换文件的事实有关$scope.pageTitle
.
使用<h1>{{ pageTitle | translate }}</h1>
和时$scope.pageTitle = 'HELLO_WORLD';
,翻译工作从第一次起完美.这个问题是我并不总是想要使用翻译(例如,对于第二个控制器,我只想传递一个原始字符串).
这是一个已知的问题/限制吗?怎么解决这个问题?
Rob*_*len 139
我建议让你的控制器免于翻译逻辑,并直接在你的视图中翻译你的字符串,如下所示:
<h1>{{ 'TITLE.HELLO_WORLD' | translate }}</h1>
Run Code Online (Sandbox Code Playgroud)
Angular Translate提供$translate
您可以在控制器中使用的服务.
该$translate
服务的示例用法可以是:
.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) {
$translate('PAGE.TITLE')
.then(function (translatedValue) {
$scope.pageTitle = translatedValue;
});
});
Run Code Online (Sandbox Code Playgroud)
translate服务还有一个直接翻译字符串的方法,无需处理promise,使用$translate.instant()
:
.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) {
$scope.pageTitle = $translate.instant('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
});
Run Code Online (Sandbox Code Playgroud)
使用的缺点$translate.instant()
可能是,如果您正在加载异步,则尚未加载语言文件.
这是我的首选方式,因为我不必以这种方式处理承诺.过滤器的输出可以直接设置为范围变量.
.controller('TranslateMe', ['$scope', '$filter', function ($scope, $filter) {
var $translate = $filter('translate');
$scope.pageTitle = $translate('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
});
Run Code Online (Sandbox Code Playgroud)
由于@PascalPrecht是这个令人敬畏的库的创建者,我建议继续他的建议(参见下面的答案)并使用提供的指令,它似乎处理非常聪明的翻译.
该指令负责异步执行,并且在转换没有动态值的情况下也非常聪明地监视范围上的转换ID.
Pas*_*cht 122
实际上,你应该使用translate指令代替这些东西.
<h1 translate="{{pageTitle}}"></h1>
Run Code Online (Sandbox Code Playgroud)
该指令负责异步执行,并且在转换没有动态值的情况下也非常聪明地监视范围上的转换ID.
但是,如果没有办法,你真的必须$translate
在控制器中使用服务,你应该在一个$translateChangeSuccess
事件中使用这样$rootScope
的组合来包装调用$translate.instant()
:
.controller('foo', function ($rootScope, $scope, $translate) {
$rootScope.$on('$translateChangeSuccess', function () {
$scope.pageTitle = $translate.instant('PAGE.TITLE');
});
})
Run Code Online (Sandbox Code Playgroud)
那么为什么$rootScope
不$scope
呢?原因在于,在angular-translate的事件中$emit
编辑$rootScope
而不是$broadcast
编辑,$scope
因为我们不需要通过整个范围层次结构进行广播.
为什么$translate.instant()
而不仅仅是异步$translate()
?当$translateChangeSuccess
事件被触发时,它确保所需的转换数据存在并且没有发生异步执行(例如异步加载器执行),因此我们可以使用$translate.instant()
哪个是同步的并且只是假设转换可用.
从版本2.8.0开始,还会$translate.onReady()
返回一个在转换准备就绪后立即解决的承诺.请参阅更改日志.
Nik*_*los 68
编辑:请参阅PascalPrecht(angular-translate的作者)的答案,以获得更好的解决方案.
加载的异步性质导致问题.你看,{{ pageTitle | translate }}
Angular将观看表达; 加载本地化数据时,表达式的值会更改并更新屏幕.
所以,你可以自己做:
.controller('FirstPageCtrl', ['$scope', '$filter', function ($scope, $filter) {
$scope.$watch(
function() { return $filter('translate')('HELLO_WORLD'); },
function(newval) { $scope.pageTitle = newval; }
);
});
Run Code Online (Sandbox Code Playgroud)
但是,这将在每个摘要周期运行观察表达式.这是次优的,可能会也可能不会导致可见的性能下降.无论如何它是Angular所做的,所以它不能那么糟糕......
要在控制器中进行翻译,您可以使用$translate
service:
$translate(['COMMON.SI', 'COMMON.NO']).then(function (translations) {
vm.si = translations['COMMON.SI'];
vm.no = translations['COMMON.NO'];
});
Run Code Online (Sandbox Code Playgroud)
该语句仅在激活控制器时执行转换,但不会检测语言的运行时更改。为了实现该行为,您可以监听$rootScope
事件:$translateChangeSuccess
,并在该处执行相同的翻译:
$rootScope.$on('$translateChangeSuccess', function () {
$translate(['COMMON.SI', 'COMMON.NO']).then(function (translations) {
vm.si = translations['COMMON.SI'];
vm.no = translations['COMMON.NO'];
});
});
Run Code Online (Sandbox Code Playgroud)
当然,您可以将$translate
服务封装在一个方法中,然后在控制器和$translateChangeSucess
侦听器中调用它。
归档时间: |
|
查看次数: |
165150 次 |
最近记录: |