AngularJS:初始化异步数据业务 [英] AngularJS : Initialize service with asynchronous data

查看:244
本文介绍了AngularJS:初始化异步数据业务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,我想用一些异步数据初始化一个AngularJS服务。事情是这样的:

I have an AngularJS service that I want to initialize with some asynchronous data. Something like this:

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的回来我会得到一个空指针异常。至于从阅读一些其他的问题,我可以告诉问<一个href=\"http://stackoverflow.com/questions/12657389/angularjs-load-service-then-call-controller-and-render\">here和 我有几个选择,但没有人似乎很干净(也许我失去了一些东西):

Obviously this won't work because if something tries to call doStuff() before myData gets back I will get a null pointer exception. As far as I can tell from reading some of the other questions asked here and here I have a few options, but none of them seem very clean (perhaps I am missing something):

与跑的设置服务

当设置我的应用程序做到这一点:

When setting up my app do this:

myApp.run(function ($http, MyService) {
    $http.get('data.json').success(function (data) {
        MyService.setData(data);
    });
});

然后,我的服务是这样的:

Then my service would look like this:

myModule.service('MyService', function() {
    var myData = null;
    return {
        setData: function (data) {
            myData = data;
        },
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

本作品一些时间,但如果异步数据恰好比它采取了一切办法去初始化我得到一个空指针异常,当我打电话给需要更长的时间 doStuff()

This works some of the time but if the asynchronous data happens to take longer than it takes for everything to get initialized I get a null pointer exception when I call doStuff()

使用承诺对象

这可能会工作。唯一的缺点是我到处打电话为MyService我必须知道,doStuff()返回一个承诺,所有code将有我们然后与承诺互动。我宁愿只是等待,直到myData的是回到加载我的申请。

This would probably work. The only downside it everywhere I call MyService I will have to know that doStuff() returns a promise and all the code will have to us then to interact with the promise. I would rather just wait until myData is back before loading the my application.

手动引导

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变量:

Global Javascript Var I could send my JSON directly to a global Javascript variable:

HTML

<script type="text/javascript" src="data.js"></script>

data.js:

data.js:

var dataForMyService = { 
// myData here
};

然后它会初始化时可为MyService

myModule.service('MyService', function() {
    var myData = dataForMyService;
    return {
        doStuff: function () {
            return myData.getSomeData();
        }
    };
});

这将工作太,但后来我有难闻的全球javascript变量。

This would work too, but then I have a global javascript variable which smells bad.

这些是我唯一的选择吗?是这些选项的比别人更好的?我知道这是一个pretty长的问题,但是我想表明我曾试图去探索我的所有选项。任何指导,将大大AP preciated。

Are these my only options? Are one of these options better than the others? I know this is a pretty long question, but I wanted to show that I have tried to explore all my options. Any guidance would greatly be appreciated.

推荐答案

你吃过一看<一个href=\"https://docs.angularjs.org/api/ngRoute/provider/%24routeProvider\"><$c$c>$routeProvider.when('/path',{解析:{...} ?它可以使承诺的做法有点清洁:

Have you had a look at $routeProvider.when('/path',{ resolve:{...}? It can make the promise approach a bit cleaner:

在暴露你的服务承诺:

Expose a promise in your service:

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;
      }
    }})
  }):

您控制器将不会被实例化的所有相关性解决前:

Your controller won't get instantiated before all dependencies are resolved:

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

我做的plnkr一个例子:<一href=\"http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=$p$pview\">http://plnkr.co/edit/GKg21XH0RwCMEQGUdZKH?p=$p$pview

这篇关于AngularJS:初始化异步数据业务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆