2016-08-10 83 views
0

我使用的角度,並有以下服務:Angular:在我設置控制器中的返回值之前,如何等待服務中的承諾解決?

myApp.factory('MyService', ['$http', function ($http) { 
    return { 
     getData: function (ID) { 
      var promise = $http.get('Holdings/GetGridData?Id=' + ID) 
      .then(function (response) { 
       return response.data; 
      }); 
      return promise; 
    }}; 
}]); 

,然後我打電話,在我的控制器使用:

function createData(ID) { 
    MyService.getData(ID).then(function (data) { 
     $scope.JsonData = data; 
    }); 

    return $scope.JsonData; 
}; 

然而,當CreateData首先被燒成則返回undefined,並經過這是返回,我可以在控制檯中看到我可以看到它顯示:XHR完成加載:GET「http://localhost:50243/Holdings/GetGridData?Id=2」。

因此,它正確地讀取數據,但在我的$ scope.JsonData設置爲undefined後。在此之後,當我再次觸發事件時,$ scope.JsonData被正確設置爲數據。我的問題是,在事件第一次被解僱時,如何讓控制器在設置值之前等待服務中的承諾解決?

+0

它是路由控制器嗎?如果是這樣,你使用什麼路由器? –

回答

0

恐怕這是不可能的。你爲什麼不喜歡控制器中的承諾方法?

函數的第一次調用將返回undefined。同時,承諾已解決,值的範圍設置,這觸發$消化週期。

0

你在promise之前返回response.data,你實際上並沒有從服務中返回http請求本身。

另外,您不需要在控制器中返回任何東西。最簡單的方法就是返回服務中的$ http請求並處理控制器中的響應。

例子:https://jsfiddle.net/bmopcr97/

function AppCtrl($scope, Service) { 
    var ID = 123; 
    Service.getData(ID).then(function(response) { 
    $scope.JsonData = response.data; 
    }); 
} 

function Service($http) { 
    return { 
    getData: function(ID) { 
     return $http.get('Holdings/GetGridData?Id=' + ID); 
    } 
    } 
} 
0

一個偉大的方式來處理,這是通過你的路由器的解析器。下面是在angular的默認路由器中使用解析器的示例(如果使用ui-router,則有點不同,但概念相同)。

$routeProvider 
    .when("/news", { 
     templateUrl: "newsView.html", 
     controller: "newsController", 
     resolve: { 
      message: function(messageService){ 
       return messageService.getMessage(); 
     } 
    } 
}); 

這裏,messageService.getMessage()返回一個承諾(類似於你的榜樣作用getData())。如果您在控制器中包含message作爲參數,則控制器將在執行前等待承諾解決。

0
You need to defer, resolve and return your promises in a 'Factory' or 'Services' file. 
Then make a call to the respective method in the Factory file in your 'Controller' file. 
Factories and Controllers perform totally different functions. All your API calls will 
have to be your 'Factory' file and then you can manipulate your data in your 
'Controller' 

Refer to example below : 

//------------------------------------------------------------------------------------ 
# user.factory.js 
# 'app.foo.user' refers to your directory structure i.e. app/foo/user/user.factory.js 

(function() { 
    'use strict'; 

    angular 
     .module('app.foo.user', []) 
     .factory('userSvc', UserService); 

    /* @ngInject */ 
    function UserService(
     $log, 
     $q, 
     $http, 
     $window, 
     $state, 
     logger, 
     session, 
     utils, 
     API_CONFIG) { 

     var ENDPOINTS = { 
      USERS: '/v1/users' 
     }; 

     /** 
     * @ngdoc service 
     * @name app.foo.user 
     * @description User management 
     */ 
     var service = { 
      get: get 
     }; 

     /** 
     * @ngdoc method 
     * @name get 
     * @description Returns all users 
     * @methodOf app.foo.user 
     * @returms {promise} user or null if not found 
     */ 
     function get() { 
      var q = $q.defer(); 

      var request = utils.buildAuthRequest(session, 'GET', ENDPOINTS.USERS); 

      $http(request) 
       .success(function (users) { 
        q.resolve(users.result); 
       }) 
       .error(function (error) { 
        logger.error('UserService.get > Error ', error); 

      return q.promise; 
     } 
    } 
})(); 

//------------------------------------------------------------------------------------ 
# user.module.js 
# 'app.foo.user' refers to your directory structure i.e. app/foo/user/user.module.js 

(function() { 
    'use strict'; 

    angular 
     .module('app.foo.user', [ 
     ]); 
})(); 

//------------------------------------------------------------------------------------ 
# user-list.controller.js 
# This is where you make a call to the 'get' method in the 'user.factory.js' where the promises 
# were defered, resolved and returned. 
# And you gave to inject 'userSvc' in this file so as to connect to the 'user.factory.js' file. 
# 'app.foo.admin' refers to your directory structure i.e. app/foo/admin/user-list.controller.js 

(function() { 
    'use strict'; 

    angular 
     .module('app.foo.admin') 
     .controller('UsersListController', UsersListController); 

    /* @ngInject */ 

    function UsersListController(
     $scope, 
     $state, 
     $timeout, 
     $log, 
     userSvc) { 
     var vm = this; 
     vm.loading = false; 
     vm.userSvc = userSvc; 

     activate(); 

     function activate() { 
      // init users 
      vm.userSvc.get().then(
       function(users) { 
        vm.users = users; 
       }, 
       function(error) { 
        $log.error(error); 
       } 
      ); 
     } 
    } 
})(); 
相關問題