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

Can't assign object returned by service to $scope

我正在尝试将服务返回的数据分配给 $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>

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

app.service('StoreService', ['$http', function ($http) {
    this.getStoreNamesService = function () {
        return $http.get('http://localhost:8080/storys');
    };
}]);

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

或者你可以创建一个延迟对象,它类似于返回一个承诺,除了它只是 returns 数据而不是 $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;
    });
}]);

$q

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

这应该有效:

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

您只能在 promise 解决后才可以为变量 storeNames 赋值。按照您的方式,承诺已分配给变量。

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

你错了两件事

  1. 您应该 return promise 对象 return 通过来自服务方法 getStoreNames 的 $http 方法。
  2. 您不应该将 $scope(上下文) 传递给服务来修改它。
  3. 您应该使用 .then 函数从 promise 对象中获取值。

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

控制器

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