我有一个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回来,我会得到一个空指针异常。据我可以从阅读一些其他问题here和here我有几个选项,但没有一个看起来很干净(也许我错过了一些东西):
设置服务与“运行”
设置我的应用程序时执行以下操作:
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变量闻到坏。
这些是我唯一的选择吗?这些选项之一比其他选项更好吗?我知道这是一个很长的问题,但我想表明,我试图探讨我的所有选择。任何指导将非常感激。
你看看
原文链接:https://www.f2er.com/angularjs/147674.html$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做了个例子