我在我的angularjs app上遇到了一个奇怪的行为。
基本上,我有一个从JSON文件加载数据的服务。
我从这项服务中有两个选择:
1-加载所有数据
2-仅根据URL
加载我需要的数据
这是服务代码:
.service ('myService', ['$http', '$stateParams', '$q', function ($http, $stateParams, $q){
var myService = this;
var defer = $q.defer();
myService.all = {};
myService.one = {};
myService.all = function (){
$http.get('data.json').success(function (res){
myService.all = res.data;
defer.resolve(res.data)
})
return defer.promise;
}
myService.one = function (urlID){
$http.get('data.json').success(function(res) {
angular.forEach(res.data, function(item) {
console.log (item, parseInt(urlID))
if (item.id === parseInt(urlID)) {
console.log("id equality: true")
myService.oneZone = item;
} else {console.log("id equality: false")}
});
});
return defer.promise
}
return myService;
}])
然后我从我的控制器那里调用它:
.controller('detailsCtrl', ['$scope', '$stateParams', 'myService', function($scope, $stateParams, myService) {
$scope.fromURL = $stateParams.myID
myService.one($scope.fromURL).then(function(res){
$scope.onlyOne = myService.oneZone
})
}])
但数据显示错误。
在这里更容易看到它的实际应用:https://plnkr.co/edit/qBtT5gkVSkYfjbngZVqw?p=preview
要重现这一点,请按以下步骤操作:
1-打开后,点击任意按钮(例如 2 )
2-以下页面将有一个空范围(仅称为One)
3-返回并点击另一个按钮(例如 3 )
4- onlyOne范围来自您按下的第一个按钮( 2 )
为什么要这样做?
感谢
答案 0 :(得分:1)
Promise只能解决一次,它总会返回相同的值。如果要更改已解析的值,则必须创建新的承诺。除了承诺在这里是多余的,你可以简化代码:
myService.all = function (){
return $http.get('data.json').success(function (res){
myService.all = res.data;
return res.data;
})
}
并且不推荐使用.success方法你应该使用.then。
用.then它可能看起来像这样:
myService.all = function (){
return $http.get('data.json').then(function (res){
myService.all = res.data.data;
return res.data.data;
})
}
还有一件事,你可以将第二个功能改为:
myService.one = function (urlID){
return $http.get('data.json').success(function(res) {
angular.forEach(res.data, function(item) {
console.log (item, parseInt(urlID))
if (item.id === parseInt(urlID)) {
console.log("id equality: true")
myService.oneZone = item;
} else {console.log("id equality: false")}
});
return myService.oneZone;
});
}
Angular会自动将.success调用的返回包装到已解决的promise中;
答案 1 :(得分:1)
问题是你必须为myService.one创建另一个promise并解决它。
myService.one = function (urlID){
var defer = $q.defer();
$http.get('data.json').success(function(res) {
angular.forEach(res.data, function(item) {
console.log (item, parseInt(urlID))
if (item.id === parseInt(urlID)) {
console.log("id equality: true")
myService.oneZone = item;
} else {console.log("id equality: false")}
});
defer.resolve(myService.oneZone);
});
return defer.promise
}
这是工作的plnkr https://plnkr.co/edit/TgClvkqUFL7g9KGiug4m?p=preview