微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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回来,我会得到一个空指针异常。据我可以从阅读一些其他问题herehere我有几个选项,但没有一个看起来很干净(也许我错过了一些东西):

设置服务与“运行”

设置我的应用程序时执行以下操作:

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()

使用promise对象

这可能工作。唯一的缺点,无处不在我调用MyService我将不得不知道doStuff()返回一个promise,所有的代码将有我们,然后与promise交互。我宁愿只是等待,直到myData返回,然后加载我的应用程序。

手动引导

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变量
我可以将我的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变量闻到坏。

这些是我唯一的选择吗?这些选项之一比其他选项更好吗?我知道这是一个很长的问题,但我想表明,我试图探讨我的所有选择。任何指导将非常感激。

你看看 $routeProvider.when('/path',{ resolve:{...}吗?它可以使promise方法更清洁:

在您的服务中公开承诺:

app.service('MyService',function($http) {
    var myData = null;

    var promise = $http.get('data.json').success(function (data) {
      myData = data;
    });

    return {
      promise:promise,setData: function (data) {
          myData = data;
      },doStuff: function () {
          return myData;//.getSomeData();
      }
    };
});

将解析添加到您的路由配置:

app.config(function($routeProvider){
  $routeProvider
    .when('/',{controller:'MainCtrl',template:'<div>From MyService:<pre>{{data | json}}</pre></div>',resolve:{
      'MyServiceData':function(MyService){
        // MyServiceData will also be injectable in your controller,if you don't want this you Could create a new promise with the $q service
        return MyService.promise;
      }
    }})
  }):

解决所有依赖性之前,您的控制器将无法实例化:

app.controller('MainCtrl',function($scope,MyService) {
  console.log('Promise is Now resolved: '+MyService.doStuff().data)
  $scope.data = MyService.doStuff();
});

我在plnkr:http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=preview做了个例子

原文地址:https://www.jb51.cc/angularjs/147674.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐