Angularjs:将一个工厂调用中的数据存储到变量中,以便在另一个工厂调用中使用

Angularjs:将一个工厂调用中的数据存储到变量中,以便在另一个工厂调用中使用,angularjs,ionic,Angularjs,Ionic,我对angularjs和ionic完全陌生。我尝试将从工厂调用收到的4个值存储到4个变量中,我需要将这些变量用作另一个函数中$http get调用的参数: 以下是我的控制器开头定义的4个变量: var firstId; var firstTimestamp; var lastId; var lastTimestamp; .controller('PicturesCtrl', function($scope, $ionicLoading, ContentFactory) { $scope.

我对angularjs和ionic完全陌生。我尝试将从工厂调用收到的4个值存储到4个变量中,我需要将这些变量用作另一个函数中$http get调用的参数:

以下是我的控制器开头定义的4个变量:

var firstId;
var firstTimestamp;
var lastId;
var lastTimestamp; 
.controller('PicturesCtrl', function($scope, $ionicLoading,  ContentFactory) {

$scope.albums = [];

var firstId;
var firstTimestamp;
var lastId;
var lastTimestamp; 

ContentFactory.getAlbums().then(function(albums){
  $scope.albums = albums;
  firstId = albums.first_id;
  firstTimestamp = albums.first_timestamp;
  lastId = albums.last_id;
  lastTimestamp = albums.last_timestamp;

  // console.log(firstId);  -> values are correctly stored
  // console.log(firstTimestamp); -> values are correctly stored
  // console.log(lastId); -> values are correctly stored
  // console.log(lastTimestamp); -> values are correctly stored

 });


$scope.loadOlderAlbums = function(lastId, lastTimestamp) {
 ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){
    $scope.albums = $scope.albums.concat(albums);
    $scope.$broadcast('scroll.infiniteScrollComplete');
 });
};

})
我从以下工厂调用中接收数据,并将数据分配给变量:

ContentFactory.getAlbums().then(function(albums){

   $scope.albums = albums;

   firstId = albums.first_id;
   firstTimestamp = albums.first_timestamp;
   lastId = albums.last_id;
   lastTimestamp = albums.last_timestamp;
});
然后,我尝试将这些变量用作对我的工厂的另一次调用的参数(在视图中调用loadOlderAlbums):

检查我的工厂时,变量lastId和lastTimestamp未定义:

getOlderAlbums : function(lastId, lastTimestamp){
        console.log(lastId); // lastId is undefined
        return $http.get('http://api.domain.xxx/albums/city/1? &direction=before&id=' + lastId + '&time=' + lastTimestamp + '&api_key=******&lang=en').then(function(response) {
                albums = response.data;
                return albums;
        });
    }
在控制台中,我看到以下错误:

GET http://api.domain.xxx/albums/city/1?&direction=before&id=undefined&time=undefined&api_key=***&lang=en 500 (Internal Server Error)
因为id和时间未定义

以下是完整的控制器:

var firstId;
var firstTimestamp;
var lastId;
var lastTimestamp; 
.controller('PicturesCtrl', function($scope, $ionicLoading,  ContentFactory) {

$scope.albums = [];

var firstId;
var firstTimestamp;
var lastId;
var lastTimestamp; 

ContentFactory.getAlbums().then(function(albums){
  $scope.albums = albums;
  firstId = albums.first_id;
  firstTimestamp = albums.first_timestamp;
  lastId = albums.last_id;
  lastTimestamp = albums.last_timestamp;

  // console.log(firstId);  -> values are correctly stored
  // console.log(firstTimestamp); -> values are correctly stored
  // console.log(lastId); -> values are correctly stored
  // console.log(lastTimestamp); -> values are correctly stored

 });


$scope.loadOlderAlbums = function(lastId, lastTimestamp) {
 ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){
    $scope.albums = $scope.albums.concat(albums);
    $scope.$broadcast('scroll.infiniteScrollComplete');
 });
};

})
工厂:

.factory('ContentFactory', function($http) {

var albums = [];

return {



    getAlbums : function(){
        return $http.get('http://api.domain.xxx/albums/city/1?lang=en&api_key=***').then(function(response) {
                albums = response.data;
                return albums;
        });
    },


    getOlderAlbums : function(lastId, lastTimestamp){
        console.log(lastId); // lastId is undefined
        return $http.get('http://api.domain.xxx/albums/city/1?&direction=before&id=' + lastId + '&time=' + lastTimestamp + '&api_key=***&lang=en').then(function(response) {
                albums = response.data;
                return albums;
        });
    }
   }
})
我们非常感谢您提供任何帮助,以找出为什么变量的值没有传递给第二个工厂调用。这可能是一个合乎逻辑的问题,因为我完全是个新手;)

更新:

请在下面找到我在Content.Factory.getAlbums中第一次调用$http GET时收到的响应示例

{
"city_id": 1,
"total_pages": 199,
"total_results": 3977,
"first_id": 15448,
"first_timestamp": 1437230820,
"results": [
    {
        "album_id": "15448",
        "title": "MAD pres. Splash The Madness Party at Aftermoon",
        "description": "The MAD crew is back and returned to Aftermoon for a night of Melbourne Bounce, Hip Hop, Big Room, Electro- and Progressive House. At the decks were Dam-Sib-Dao, Beatender, Madz Mellow & Odyszey, supported by Mc Ben10.",
        "photographer_id": "8",
        "photographer_name": "ploy",
        "image_count": "88",
        "cover_image": "5dd26da7f37da641d775568d2e98ae44.jpg",
        "date": "2015-07-18 21:47:00",
        "location_id": "705",
        "location_name": "Aftermoon"
    },
    {
        "album_id": "15446",
        "title": "Superhero Charity Party at KU DÉ TA Bangkok",
        "description": "KU DÉ TA Bangkok and the charity organisation \"Habitat for Humanity Thailand\" joined forces for the SUPERHERO “CHARITY PARTY\". Habitat for Humanity Thailand improves the quality of Thai people’s lives through building homes and transforming communities. Entry is Free, but there guests are invited to do a FREE-WILL DONATION of which 100% will go to Habitat for Humanity Thailand to build houses under the program “Make Her Day” in Pathumthani.",
        "photographer_id": "15",
        "photographer_name": "win",
        "image_count": "176",
        "cover_image": "742a0065d046418041175ff8005d7174.jpg",
        "date": "2015-07-18 18:46:00",
        "location_id": "809",
        "location_name": "KU DÉ TA"
    }
],
"last_id": 15427,
"last_timestamp": 1437062520
}
$scope.loadOlderAlbums在我的视图中被调用(Ionic无限滚动)


更改获取旧相册的$scope方法。您希望传入这些参数,但在调用它时,它们应该已经在您的控制器作用域中定义好了,所以实际上不需要这样做

看到你没有将
lastId
lastTImestamp
暴露在
这个
$scope
上,这让我相信在你看来你是这样调用这个方法的:

<button ng-click="loadOlderAlbums()">Load more albums</button>
现在,您不必将lastId或lastTimestamp传递到函数中(正如您之前所要求的那样)


如果您确定在开始滚动之前启动了
getAlbums()
调用,那么以下操作应该可以正常工作(编辑了一组代码以突出重点):

通过在其中添加
throw
语句,您可以验证是否存在:

  • lastId
    lastTimeStamp
    变量的存储(通过getAlbums)/使用(通过loadOlderAlbums)中的竞争条件
  • 或者它神奇地开始工作

由于您使用的是离子型路由器,而离子型路由器又使用ui路由器;您可以将对
getAlbums
的调用移动到a中,并确保在开始滚动之前将数据加载到控制器中

这可能看起来像:

.state('...', {
  controller: 'PicturesCtrl',
  resolve: {
    preloadedAlbums: function (ContentFactory) { // available for DI later into your controller.
      return ContentFactory.getAlbums().then(function (response) {
        return {
          albums:  response,
          firstId: response.first_id,
          firstTimeStamp: response.first_timestamp,
          lastId: response.last_id,
          lastTimeStamp: response.last_timestamp
        }; 
      });
    }
  }
}
现在,当您尝试导航到所述状态时,resolve对象将在调用控制器之前获取其内容。因此,您可以确保在用户开始在
PicturesCtrl
范围内滚动之前,数据已经存在,并且
loadMoreAlbums
所需的参数也将存在

您的
PicturesCtrl
现在可以看到以下内容:

.controller('PicturesCtrl', function ($scope, $ionicLoading,  ContentFactory, preloadedAlbums) {

  $scope.albums = preloadedAlbums;

  var lastId = preloadedAlbums.lastId;
  var lastTimeStamp = preloadedAlbums.lastTimeStamp; 
  /** etc **/ 
});

我会尝试第一个建议(使用
抛出
),以确保导致您的问题的原因是
getAlbums
承诺没有得到解决。然后我会考虑移到<代码>解析< /代码>块。

如果这还不能根除问题的根源,我会用
调试器
来破坏代码库,并从头到尾逐步验证到底发生了什么

$scope.albums是否实际加载?如果您能向我们展示实际加载到$scope.albums中的内容,将会有所帮助。您实际在哪里调用
$scope.loadOlderAlbums()
?调用它时,首先要检查参数是否未定义Install batarang,以便检查和比较作用域。@Daniel Cottone感谢您的帮助。我已经用我的GET电话中的一个示例响应更新了我的问题$已加载scope.albumscorrectly@charlietfl[code]$scope.loadOlderAlbums()在我的视图中被调用。亲爱的Kaspar,谢谢你试图帮助我,真的很感激。我刚刚看到你对你的问题所做的编辑,似乎我在钱上是对的:)如果你像现在在控制器中实现的那样调用函数(从视图)没有任何传递的参数-
lastId
lastTimestamp
将是未定义的。是的,该方法在我的视图中被调用(它是ionic infinite scroll的一部分)。我更新了我的问题以包括视图部分。lastId和lastTimestamp是ContentFactory的第一个GET响应的一部分。getAlbums()。我试图更改代码以包含您的建议,但仍不起作用。在对我的API的第二次调用中,lastId和lastTimestamp仍然未定义。如果需要更多帮助,将不胜感激。请参阅我的最新编辑。有关如何根除/定位问题以及可能修复问题的一些建议(当然取决于问题的实际情况).非常感谢你的精彩更新;)我会看一看,然后玩一玩。承诺尽快给你反馈。
var loaded = false;

function getAlbums () {
   $http.get('albums').then(function (res) {
     /** set the ID's and timestamps **/ 
     loaded = true;
   });
}

function loadOlderAlbums () {
  if (!loaded) {
    throw new Error('Yep, nope. We have to get some other albums first. Sorry!');
  }

  /** your old loadOlderAlbums implementation **/ 
}
.state('...', {
  controller: 'PicturesCtrl',
  resolve: {
    preloadedAlbums: function (ContentFactory) { // available for DI later into your controller.
      return ContentFactory.getAlbums().then(function (response) {
        return {
          albums:  response,
          firstId: response.first_id,
          firstTimeStamp: response.first_timestamp,
          lastId: response.last_id,
          lastTimeStamp: response.last_timestamp
        }; 
      });
    }
  }
}
.controller('PicturesCtrl', function ($scope, $ionicLoading,  ContentFactory, preloadedAlbums) {

  $scope.albums = preloadedAlbums;

  var lastId = preloadedAlbums.lastId;
  var lastTimeStamp = preloadedAlbums.lastTimeStamp; 
  /** etc **/ 
});