无法将服务返回的对象分配给 $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()
。
你错了两件事
- 您应该 return promise 对象 return 通过来自服务方法
getStoreNames
的 $http 方法。
- 您不应该将
$scope
(上下文) 传递给服务来修改它。
您应该使用 .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;
});
我正在尝试将服务返回的数据分配给 $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()
。
你错了两件事
- 您应该 return promise 对象 return 通过来自服务方法
getStoreNames
的 $http 方法。 - 您不应该将
$scope
(上下文) 传递给服务来修改它。 您应该使用
.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;
});