Javascript 在异步(ajax)调用后将服务/对象注入控制器
我目前正在全球化一个用ASP.NETMVC和AngularJS开发的网站。对于我用来加载资源包的JS部分 现在我有一个这样的控制器:Javascript 在异步(ajax)调用后将服务/对象注入控制器,javascript,angularjs,Javascript,Angularjs,我目前正在全球化一个用ASP.NETMVC和AngularJS开发的网站。对于我用来加载资源包的JS部分 现在我有一个这样的控制器: app.controller('MyController', ['$scope', function($scope) { $scope.msg = "Hello World!"; }]); 使用ngLocalize,我可以使用locale服务,在回调中获取资源字符串: app.controller('MyController', ['$scope', 'lo
app.controller('MyController', ['$scope', function($scope) {
$scope.msg = "Hello World!";
}]);
使用ngLocalize,我可以使用locale服务,在回调中获取资源字符串:
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
locale.ready('ResourceFile').then(function() {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
});
}]);
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
}]);
问题是,我必须翻译数百个字符串,引入回调使代码很难查看,有时还迫使我更改控制器逻辑(例如:当我需要函数中的资源字符串向调用方返回消息时)。我想直接调用locale.getString(),无需回调:
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
locale.ready('ResourceFile').then(function() {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
});
}]);
app.controller('MyController', ['$scope', 'locale', function($scope, locale) {
$scope.msg = locale.getString('ResourceFile.HelloWorld');
}]);
也许可以在初始化控制器之前调用locale.ready()承诺,从而在locale服务中预加载资源文件
请记住,我处理的是遗留代码,而网站不是单页应用程序,因此我无法使用routeProvider/resolve(显然)不是这里的选项
任何洞察都将不胜感激。解决这一问题的理想方法是使用ng route或ui router的
resolve
功能,因为只有resolve
中的数据可用时,才会实例化视图/控制器
你也可以做同样的事情,尽管不那么优雅:
<div ng-if="dataIsAvailable>
<div ng-controller="MyController"></div>
</div>
将所有内容放在一起:
应用程序启动时,预加载URL的(MyLocaleService.loadResource())。推迟视图/控制器的实例化,直到使用
ng if
或类似方法获得数据。将MyLocalService
注入控制器,并使用它获取资源包字符串。因此查看文档ngLocalize已经有了一个过滤器。
因此,在html中,您可以执行以下操作
<span>{{ 'Resourcefile.HelloWorld' | i18n }}</span>
经过许多努力,我终于找到了一个更适合我的案例的解决方案(编辑:有一个更好的解决方案-见下文) 它包括:1)将ngLocalize服务注入dummyApp,2)手动引导“真实”应用。我怀疑这段代码可以改进(很多),但至少现在它解决了我的问题:
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');
});
});
它实际上非常简单,我很惭愧以前从未想过它您可以编写一个过滤器来执行local.getString,这样就不需要每次传入字符串time@Teliren谢谢你的评论。你能更具体地谈谈你的想法吗?再次感谢你。不幸的是,我需要在更复杂的用例中使用翻译后的字符串。e、 g:notifyService.error(locale.getString(…);对不起,在我的问题中,我应该更清楚这一点。这是解决我问题的一个可接受的解决方案,我将不得不更改几十个页面的标记,但这比更改几十个控制器以使用“解析”功能要好,因为这是一个遗留应用程序。谢谢你的详细回答!
sampleApp.controller('SampleController', ['$scope', 'locale', function ($scope, locale) {
locale.ready(['Common', 'MyResource1', 'MyResource2']).then(function() {
$scope.msg = locale.getString('MyResource1.Value1');
});
});