2016-11-20 6 views
1

Я пытаюсь назначить данные, возвращенные службой, в свойство $ 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, он дает мне undefined также на представлениях нет данных.

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> 
+1

Это происходит потому, что AJAX вызов не завершен, и ваша функция возвращает befote что. Либо отправьте обратный вызов с помощью $ scope в качестве параметра, либо еще лучше используйте Promise – bugwheels94

ответ

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().

0

При использовании Угловое вы лучше возвращающая обещание, служба $ HTTP возвращает обещание, и вы можете переведите обратный вызов успеха в область:

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

Или вы можете создать отложенный объект, который подобен в на обещание возвращается, за исключением того, что просто возвращает данные, а не коды состояния $ 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

В обоих случаях объект охват должен быть заполнен внутри контроллера.

1

Пара вещей, которые вы ошибались

  1. Вы должны вернуть возврат объекта обещание $ методом HTTP от метода обслуживания getStoreNames.
  2. Вы не должны передавать $scope (контекст) для обслуживания, чтобы изменить его.
  3. Вы должны использовать функцию .then, чтобы получить значение от объекта обещания.

    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; 
}); 
Смежные вопросы