我有一个带服务和控制器的Angular应用程序:
service.js
.factory('MyService', function ($http, $q) {
var api_url = 'http://localhost/api/';
var MyService = {
list: function (items_url) {
var defer = $q.defer();
$http({method: 'GET',
url: api_url + items_url}).
success(function (data, status, headers, config) {
defer.resolve(data);
}).error(function (data, status, headers, config) {
defer.reject(status);
});
return defer.promise;
},
...
}
});
controller.js
.controller("ItemsCtrl", function ($scope, MyService) {
$scope.getItems = function () {
MyService.list('items/').then(function(data) {
$scope.items = data;
});
};
$scope.addItems = function () {
$scope.getItems();
// why is this undefined ??!!!
console.log($scope.items);
};
问题是我想在$scope.getItems
方法中调用$scope.addItems
方法。我是否可能需要使用$scope.apply()
,因为返回的值是一个承诺?
我认为我在这里展示的是普遍缺乏理解。
答案 0 :(得分:3)
按照以下方式更改您的控制器:
.controller("ItemsCtrl", function ($scope, MyService) {
$scope.getItems = function () {
return MyService.list('items/').then(function(data) {
$scope.items = data;
});
};
$scope.addItems = function () {
$scope.getItems().then(function() {
// should be what you want this time
console.log($scope.items);
});
};
问题是当您致电$scope.getItems()
时,尚未返回http响应,因此未填充$scope.items
。您必须等待所有承诺决定访问items
。
答案 1 :(得分:0)
$scope.items
未定义,因为$http
是异步通信。也就是说,当您调用$scope.addItems()
时,它会创建并发送请求以检索您的项目列表,然后立即转到下一行代码,即将$scope.items
记录到控制台。由于$scope.items
中没有任何内容,因此您会得到一个未定义的值。
如果要对http调用返回的数据进行操作,则必须保证将填充数据。换句话说,您要在$scope.items
块中调用要在.then()
上执行的任何操作。
$scope.$apply()
来强制AngularJS框架评估表达式。它对你没有帮助 - 你会得到一个“已经在进行中的$ digest”错误,或类似的东西。
试试这个:
.controller("ItemsCtrl", function ($scope, MyService) {
$scope.getItems = function () {
MyService.list('items/').then(function(data) {
$scope.items = data;
console.log($scope.items);
});
};
$scope.addItems = function () {
$scope.getItems();
};
});
答案 2 :(得分:0)
这是因为$scope.getItems
是异步的。您的回调(通过那时添加)将在$scope.addItems
执行后调用。