为了账号安全,请及时绑定邮箱和手机立即绑定

AngularJS:用异步数据初始化服务

AngularJS:用异步数据初始化服务

茅侃侃 2019-06-19 15:10:49
AngularJS:用异步数据初始化服务我有一个AngularJS服务,我想用一些异步数据初始化它。就像这样:myModule.service('MyService', function($http) {     var myData = null;     $http.get('data.json').success(function (data) {         myData = data;     });     return {         setData: function (data) {             myData = data;         },         doStuff: function () {             return myData.getSomeData();         }     };});很明显,这是行不通的,因为如果有东西试图调用doStuff()以前myData获取返回,我将得到一个空指针异常。据我所知,从所问的其他问题中,我可以看出这里和这里我有几个选择,但没有一个看起来很干净(也许我遗漏了什么):带有“Run”的安装服务在设置我的应用程序时,请执行以下操作:myApp.run(function ($http, MyService) {     $http.get('data.json').success(function (data) {         MyService.setData(data);     });});那么我的服务应该是这样的:myModule.service('MyService', function() {     var myData = null;     return {         setData: function (data) {             myData = data;         },         doStuff: function () {             return myData.getSomeData();         }     };});这在某些情况下是可行的,但是如果异步数据碰巧花费的时间比初始化所用的时间更长,则当我调用时会得到一个空指针异常。doStuff()使用承诺对象这可能管用。唯一的缺点就是我在任何地方都调用MyService,我必须知道doStuff()返回一个承诺,所有的代码都必须返回给我们。then与承诺互动。我宁愿等到我的数据回来后再加载我的应用程序。手动引导angular.element(document).ready(function() {     $.getJSON("data.json", function (data) {        // can't initialize the data here because the service doesn't exist yet        angular.bootstrap(document);        // too late to initialize here because something may have already        // tried to call doStuff() and would have got a null pointer exception     });});全局Javascript Var我可以将JSON直接发送到全局Javascript变量:HTML:<script type="text/javascript" src="data.js"></script>data.js:var dataForMyService = { // myData here};当初始化时,它将是可用的。MyService:myModule.service('MyService', function() {     var myData = dataForMyService;     return {         doStuff: function () {             return myData.getSomeData();         }     };});这也是可行的,但是我有一个全局javascript变量,它闻起来很难闻。这是我唯一的选择吗?这些选择中有一个比其他的好吗?我知道这是一个很长的问题,但我想表明,我已经尝试探索我的所有选择。如有任何指导,将不胜感激。
查看完整描述

3 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

基于Martin Atkins的解,这里有一个完整、简洁的纯角度解:

(function() {
  var initInjector = angular.injector(['ng']);
  var $http = initInjector.get('$http');
  $http.get('/config.json').then(
    function (response) {
      angular.module('config', []).constant('CONFIG', response.data);

      angular.element(document).ready(function() {
          angular.bootstrap(document, ['myApp']);
        });
    }
  );})();

该解决方案使用自动执行的匿名函数获取$http服务,请求配置,并在配置可用时将其注入一个名为config的常量中。

一旦完全完成,我们将等到文档准备就绪,然后引导这个角度应用程序。

这是对Martin解决方案的轻微改进,后者将获取配置推迟到文档准备好之后。据我所知,没有理由推迟要求提供$http的费用。

单元测试

注意:当代码包含在您的代码中时,当单元测试时,我发现此解决方案不能很好地工作。app.js档案。原因是上述代码在加载JS文件时立即运行。这意味着测试框架(在我的例子中是Jasmine)没有机会提供$http.

我的解决方案,我并不完全满意,就是把这段代码移到我们的index.html文件,因此Grunt/Karma/Jasmin单元测试基础结构看不到它。


查看完整回答
反对 回复 2019-06-19
  • 3 回答
  • 0 关注
  • 647 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信