无法将服务返回的对象分配给$ scope

时间:2016-11-20 22:44:22

标签: javascript angularjs angularjs-http

我试图将服务返回的数据分配给$ scope属性。不知怎的,它不能正常工作。服务方法通过$ http.get正确获取数据,但之后未将其分配给控制器中的$ scope。

app.service('StoreService', ['$http', function ($http) {

    this.getStoreNamesService = function () {
        console.log('getStoreNames called');
        $http.get('http://localhost:8080/storys')
            .success(function (response, status) {
                console.log(response);
                return response;
            })
    };
}]);

app.controller('ItemFormController', ['$scope', '$http', '$mdDialog', 'itemService', 'StoreService', function ($scope, $http, $mdDialog, itemService, StoreService) {

    $scope.storeNames = StoreService.getStoreNamesService();
}]);

在服务中打印响应可提供正确的数据。但是,当我打印$ scope.storeNames时,它在视图上也没有定义,也没有数据。

app.js:

var app = angular.module('BlankApp', ['ngMaterial', 'ngRoute'])
.config(function($mdThemingProvider) {
    $mdThemingProvider.theme('default')
        .primaryPalette('teal')
        .accentPalette('red')
        .warnPalette('red');
});

app.config(function ($routeProvider) {
    $routeProvider
        .when('/addItem', {
            templateUrl: 'templates/addItemForm.html',
            controller: 'ItemFormController'
        })
        .when('/', {
        templateUrl: 'templates/first.html'
        })
        .when('/store', {
            templateUrl: 'templates/itemsInStore.html',
            controller: 'StoreController'
        })
        .when('/item/:itemId', {
            templateUrl: 'templates/itemView.html',
            controller: 'ItemController'
        })
        .otherwise({
            template: '<h1>otherwise template</h1>'
        })
});

脚本标签的顺序:

    <!-- Angular Material requires Angular.js Libraries -->
<script src="js/angular-1.5.8/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.min.js"></script>

<!-- Angular Material Library -->
<script src="js/AngularMaterial/angular-material.js"></script>

<!-- Your application bootstrap  -->


<script src="js/app.js"></script>
<script src="js/service/itemService.js"></script>
<script src="js/service/StoreService.js"></script>
<script src="js/controller/testController.js"></script>
<script src="js/controller/SideNavController.js"></script>
<script src="js/controller/ItemFormController.js"></script>

<script src="js/controller/sampleController.js"></script>
<script src="js/controller/ItemController.js"></script>

3 个答案:

答案 0 :(得分:1)

这应该有效:

app.service('StoreService', ['$http', function ($http) {

this.getStoreNamesService = function () {
    console.log('getStoreNames called');
    return $http.get('http://localhost:8080/storys').then(
        function success(response, status) {
            console.log(response);
            return response;
        })
    };
}]);

app.controller('ItemFormController', ['$scope', '$http', '$mdDialog', 'itemService', 'StoreService', function ($scope, $http, $mdDialog, itemService, StoreService) {
    StoreService.getStoreNamesService().then(function(result){
        $scope.storeNames = result;
    });
}]);

您只能在解析承诺后分配变量storeNames。你正在做的事情,承诺被分配给变量。

另请注意,.success()已弃用。请改用.then()

答案 1 :(得分:1)

你误解了几件事

  1. 您应该从服务方法getStoreNames返回$ http方法返回promise对象。
  2. 您不应该将$scope(上下文)传递给服务以进行修改。
  3. 您应该使用.then函数从promise对象中获取值。

    app.service('StoreService', ['$http', function ($http) {
      this.getStoreNamesService = function () {
        //return promise here
        return $http.get('http://localhost:8080/storys');
      };
    }]);
    
  4. <强>控制器

    StoreService.getStoreNamesService($scope).then(function(response){
       $scope.storeNames = response.data;
    });
    

答案 2 :(得分:0)

使用Angular时,您最好返回一个承诺,$ http服务会返回一个承诺,您可以将成功回调移动到范围:

app.service('StoreService', ['$http', '$q', function ($http, $q) {
    this.getStoreNamesService = function () {
        var deferred = $q.defer();
        $http.get('http://localhost:8080/storys').then(function(response, status){
            deferred.resolve(response.data);
        });
        return deferred;
    };
}]);

app.controller('ItemFormController', ['$scope', '$http', '$mdDialog', 'itemService', 'StoreService', function ($scope, $http, $mdDialog, itemService, StoreService) {
    StoreService.getStoreNamesService().then(function (data) {
        $scope.storeNames = data;
    });
}]);

或者您可以创建一个延迟对象,其类似于返回promise,除了它只返回数据而不是$ http状态代码等:

{{1}}

请参阅$q

在这两种情况下,都应在控制器中填充范围对象。