我目前正在全球化使用ASP.NET MVC和AngularJS开发的网站。对于JS部分,我使用angular-localization来加载资源包。
现在我有一个像这样的控制器:
app.controller('MyController', ['$scope', function($scope) {
$scope.msg = "Hello World!";
}]);
使用ngLocalize我可以使用语言环境服务,在回调中获取资源字符串:
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
locale.ready('ResourceFile').then(function() {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
});
}]);
问题是我必须翻译数百个字符串并引入回调使得很难查看代码,并且有时迫使我更改控制器逻辑(例如:当我需要返回一个函数内的资源字符串时给来电者留言)。我想直接调用locale.getString(),没有回调:
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
}]);
也许可以在初始化控制器之前调用locale.ready()promise,从而在语言环境服务中预加载资源文件。
请记住,我正在处理遗留代码而且网站不是单页应用程序,所以我不能使用routeProvider / resolve(显然)不是这里的选项。
非常感谢任何见解。
答案 0 :(得分:1)
解决此问题的理想方法是使用ng-route或ui-router中的resolve
功能,因为在resolve
的数据可用之前,视图/控制器不会被实例化。< / p>
你可以做同样的事情,虽然不那么优雅:
<div ng-if="dataIsAvailable>
<div ng-controller="MyController"></div>
</div>
在上文中,MyController
不会被实例化,直到ng-if
中的表达式为真。
现在,您需要预加载资源文件,并将其数据提供给其他应用程序组件。简单的例子:
angular.factory('MyLocaleService', function(locale) {
var MyLocaleService = function() {};
var localeData = {};
MyLocaleService.prototype.loadResource = function() {
locale.ready('ResourceFile').then(function() {
// get the data from the resource file and iterate over it to
// store the data in a local var... For this example only doing
// a simple assignment
localeData['myString'] = locale.getString('myString');
});
}
MyLocaleService.prototype.getString = function(string) {
return localeData[string];
}
return new MyLocaleService();
});
全部放在一起:
当您的应用启动时,请预先加载网址(MyLocaleService.loadResource())。延迟视图/控制器的实例化,直到使用ng-if
或类似的数据可用数据。将MyLocaleService
注入控制器并使用它来获取资源包字符串。
答案 1 :(得分:0)
所以查看文档ngLocalize已经有了一个过滤器。 所以在html中你可以做类似
的事情<span>{{ 'Resourcefile.HelloWorld' | i18n }}</span>
或
<span>{{ msg | i18n}}<span>
然后您的控制器看起来像
app.controller('MyController', ['$scope',
function($scope) {
$scope.msg = 'ResourceFile.HelloWorld';
}
]);
答案 2 :(得分:0)
经过艰苦的努力,我终于找到了一个更适合我案例的解决方案(编辑:那里有一个更好的解决方案 - 见下文)。
它涉及:1)将ngLocalize服务注入到dummyApp中,并且2)引导&#34; real&#34; app手动。我怀疑这段代码可以改进(很多),但至少它现在解决了我的问题:
var dummyApp = angular.module('dummyApp', ['ngLocalize', 'ngSanitize', 'ngCookies'])
.value('localeSupported', ['en-US', 'pt-BR'])
.value('localeConf', {...);
var sampleApp = angular.module('sampleApp', ['ngCookies']);
var RESOURCES_TO_LOAD = ['Common'];
angular.element(document).ready(function () {
var initInjector = angular.injector(["ng", "dummyApp"]);
var locale = initInjector.get("locale");
locale.ready(RESOURCES_TO_LOAD).then(function () {
angular.bootstrap(document, ['sampleApp']);
});
});
控制器逻辑如下:
// controller-specific code
var RESOURCES_TO_LOAD = ['Common', 'MyResource1', 'MyResource2'];
sampleApp.controller('SampleController', ['$scope', 'locale', function ($scope, locale) {
$scope.msg = locale.getString('MyResource1.Value1');
}]);
编辑:这是一个更简单的解决方案
sampleApp.controller('SampleController', ['$scope', 'locale', function ($scope, locale) {
locale.ready(['Common', 'MyResource1', 'MyResource2']).then(function() {
$scope.msg = locale.getString('MyResource1.Value1');
});
});
实际上这很简单,我感到很惭愧,我从未想过它