AngularJS - Controller将从Service(MVC Web API调用)返回的数据视为未定义

时间:2013-10-14 22:17:44

标签: angularjs asp.net-web-api

我是AngularJS&研究样本。在我的示例应用程序中,我有一个MVC Web api(从db返回一些数据)&它将从Angular Services调用并将数据返回给Controller。问题是我正在使用我的服务成功方法获取数据但在我的控制器中它总是显示未定义的&视图中不显示任何内容。请参阅以下代码:

我的控制器代码:

app.controller('CustomerController', function ($scope, customerService) {    
    //Perform the initialization
    init();

    function init() {
        $scope.customers= customerService.getCustomers();        
    }   
});

我的服务代码:

app.service('customerService', function ($http){
       this.getCustomers = function () {
        $http({
            method: 'GET',
            url: 'api/customer'           
        }).
    success(function (data, status, headers, config) {
        return data;
    }).
    error(function (data, status) {
        console.log("Request Failed");
    });

    }
});

请帮我解决这个问题。

4 个答案:

答案 0 :(得分:6)

您的问题出在您的服务实施中。你不能简单地return data,因为那是在异步成功回调中。

相反,您可能会返回一个承诺,然后在您的控制器中处理:

app.service('customerService', function ($http, $q){
    this.getCustomers = function () {
        var deferred = $q.defer();
        $http({
            method: 'GET',
            url: 'api/customer'           
        })
        .success(function (data, status, headers, config) {
           // any required additional processing here
           q.resolve(data);
        })
        .error(function (data, status) {
           q.reject(data);
        });
        return deferred.promise;
    }
});

当然,如果您不需要额外的处理,您也可以只返回$ http调用的结果(这也是一个承诺)。

然后在你的控制器中:

app.controller('CustomerController', function ($scope, customerService) {    
    //Perform the initialization
    init();

    function init() {
        customerService.getCustomers()
            .then(function(data) {
               $scope.customers= data;
            }, function(error) {
               // error handling here
            });        
    }   
});

答案 1 :(得分:6)

那是因为你的服务定义了函数getCustomers,但方法本身实际上并没有返回任何东西,它只是进行一次http调用。

您需要以

之类的形式提供回调函数
$http.get('/api/customer').success(successCallback);

然后让回调返回或将数据设置到控制器。要做到这一点,回调可能必须来自控制器本身。

或者更好的是,你可以使用promise来回复它。

承诺看起来像

app.service('customerService', function ($http, $q){
   this.getCustomers = function () {
       var deferred = $q.defer();
       $http({
           method: 'GET',
           url: 'api/customer'           
        }).
        success(function (data, status, headers, config) {
            deferred.resolve(data)
        }).
        error(function (data, status) {
            deferred.reject(data);
        });

        return deferred;
    }
});

答案 2 :(得分:1)

非常迟到的答案,但是,Angular的$http方法return promises,因此无需将所有内容与$q包装成承诺形式。所以,你可以:

app.service('CustomerService', function ($http) {
  this.getCustomers = function () {
    return $http.get('/api/customer');
  };
});

然后调用客户端控制器中的.success().error()快捷方式。

如果你想更进一步,并且有一个完全成熟的RESTful CustomerService而不必编写这个样板文件,我推荐使用restangular库,这会产生各种各样的您可以使用的方法 - 当然假设您的后端响应HTTP verbs in the "standard fashion"

然后你可以这样做:

app.service('CustomerService', function (Restangular) {
  return Restangular.service('api/customer');
});

并调用Restangular提供的方法。

答案 3 :(得分:0)

我将它用于Angular Web数据服务和Web Api控制器之间的通信。

.factory('lookUpLedgerListByGLCode', function ($resource) {
    return $resource(webApiBaseUrl + 'getILedgerListByGLCode', {}, {
        query: { method: 'GET', isArray: true }
    });
})

OR

.factory('bankList', function ($resource) {
    return $resource(webApiBaseUrl + 'getBanklist_p', {}, {
        post: {
            method: 'POST', isArray: false,
            headers: { 'Content-Type': 'application/json' }
        }
    });
})