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

Angularjs-使用服务加载数据会显示上一个页面数据,而不是当前页面数据,angularjs,Angularjs,我在angularjs应用程序上遇到了一个奇怪的行为 基本上,我有一个从JSON文件加载数据的服务 我从这项服务中有两种选择: 1-加载所有数据 2-根据URL仅加载我需要的数据 以下是服务代码: .service ('myService', ['$http', '$stateParams', '$q', function ($http, $stateParams, $q){ var myService = this; var defer = $q.defer(); my

我在angularjs应用程序上遇到了一个奇怪的行为

基本上,我有一个从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
    })    
}])
但数据的显示方式是错误的

在这里更容易看到它的作用:

要重现这一点,您必须做以下几点:

1-打开后,单击任何按钮(例如2

2-下一页的作用域为空(称为onlyOne)

3-返回并单击另一个按钮(例如3

4-只有一个范围来自您按下的第一个按钮(2

为什么要这样做


感谢

承诺只能解决一次,它将始终返回相同的值。如果你想改变已解决的价值,你必须创造新的承诺。除了promise在这里是多余的之外,您还可以将代码简化为:

myService.all = function (){
    return $http.get('data.json').success(function (res){
      myService.all = res.data;
      return res.data;
    })
}
另外,不推荐使用.success方法。然后

有。那么它可能会是这样的:

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将自动将返回的.成功呼叫包装为已解决的承诺

问题是你必须为myService.one创建另一个承诺并解决它

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

这是一种很好的方式来实现我想要实现的目标吗?我还真的很担心内存泄漏和一些“错误的方式”的事情,谢谢。你认为使用承诺还是不使用承诺对绩效更有利?像这样的东西你通常用什么?是的,看起来很不错。将所有.success替换为.then并删除多余的承诺创建。因此,按照您的第一个示例,直接返回数据的方法,对吗?是的,请记住类似.then.success的方法返回承诺,它将使用其回调返回值进行解析,您不必手动创建延迟对象。