我已经疯了几个小时了。
我有一个角度服务工厂来从我的API获取地址:
App.factory('storesService', ['$http', '$q', 'endpoint', function ($http, $q, endpoint) {
var deferred = $q.defer();
return {
addresses: function (store_id) {
$http.get(endpoint.store.addresses, {
params: {
id: store_id
}
})
.success(function (data) {
console.log('Data from API:' + data);
deferred.resolve(data);
})
.error(function () {
deferred.reject();
});
return deferred.promise;
}
};
}]);
我的控制器使用此服务来获取特定商店的地址:
$scope.loadAddresses = function (store_id) {
var load = storesService.addresses(store_id);
load.then(function (data) {
console.log('Deferred data:' + data);
$scope.addresses = data.addresses;
});
};
在我看来,我有ng-init="loadAddresses(store_id)"
,store_id
是正确的值。
我还使用angular-xeditable(select-local)来管理我的商店选择。
我在视图中添加onaftersave='storeChanged(store.id)'
以获取用户选择的商店ID,并正确返回新ID。
我的storeChanged
函数非常简单,它基本上会向API发送新请求:
$scope.storeChanged = function (store_id) {
$scope.loadAddresses(store_id);
};
会发生什么:
一开始,ng-init
我正确地看到the console.log
,首先是服务中的那个,然后是来自控制器的那个。
一旦我从我的选择中选择了另一个商店,我首先看到控制器中的console.log
,然后是服务中的那个。
基本上控制器中的数据没有更新,我无法理解为什么会发生......
答案 0 :(得分:1)
您正在尝试重新解决您无法做到的承诺。您只需为每个请求创建一个deferred
。这应该在addresses
函数内部,以便为每个请求创建一个新函数,但无论如何你都不需要它,因为$http
已创建并返回一个promise。您需要从$http
返回承诺,而不是创建新承诺。有关更好的理解,请参阅此帖子:What is the explicit promise construction antipattern and how do I avoid it?
addresses: function (store_id) {
return $http.get(endpoint.store.addresses, {
params: {
id: store_id
}
}).then(function(resp) {
console.log('Data from API:' + resp.data);
return resp.data;
});
}
答案 1 :(得分:1)
您在服务中定义了全局延迟,因此只有一个全局承诺。因为承诺只能被解决或拒绝一次,所以在第一次http调用后它将永远保持解决/拒绝。要修复,只需将行var deferred = $q.defer();
移动到您的服务功能中:
App.factory('storesService', ['$http', '$q', 'endpoint', function ($http, $q, endpoint) {
return {
addresses: function (store_id) {
var deferred = $q.defer();
$http.get(endpoint.store.addresses, {
params: {
id: store_id
}
})
.success(function (data) {
console.log('Data from API:' + data);
deferred.resolve(data);
})
.error(function () {
deferred.reject();
});
return deferred.promise;
}
};
}]);
答案 2 :(得分:1)
您已为潜在的许多请求创建了一个延迟。第一次提出请求时,它会起作用,但在它之后会立即返回,因为您已设置的承诺已经解决。实际上,smira模式对于缓存非常有用。
$http
已经返回一个承诺。您不需要不遗余力地使用$q
App.factory('storesService', ['$http', 'endpoint', function ($http, endpoint) {
return {
addresses: function (store_id) {
return $http.get(endpoint.store.addresses, {
params: {
id: store_id
}
}).then(function(response){
//Chain an extra promise here to clean up the response to just return the data.
return response.data;
})
}
};
}]);