在异步(ajax)调用

时间:2015-07-21 18:37:03

标签: javascript angularjs

我目前正在全球化使用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(显然)不是这里的选项。

非常感谢任何见解。

3 个答案:

答案 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');
  });
});

实际上这很简单,我感到很惭愧,我从未想过它