Angularjs - 使用服务加载数据会显示上一页数据,而不是当前页面数据

时间:2016-05-12 10:59:50

标签: angularjs

我在我的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

为什么要这样做?

感谢

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