我对angularjs和ionic更新。我尝试将从工厂调用中收到的4个值存储到4个变量中,我需要将其用作另一个函数中$ http get调用的参数:
这里是我控制器开头定义的4个变量:
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;
});
然后我尝试将这些变量用作我工厂的另一个调用的参数(在视图中调用loadOlderAlbums):
$scope.loadOlderAlbums = function(lastId, lastTimestamp) {
ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){
$scope.albums = $scope.albums.concat(albums);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
变量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&时间不确定。
这是完整的控制器:
.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(离子无限滚动)
<ion-infinite-scroll
on-infinite="loadOlderAlbums()"
distance="1%">
</ion-infinite-scroll>
答案 0 :(得分:1)
更改您的$ scope方法以获取旧相册。您希望传入参数 - 但是当您调用它们时,它们应该已经在您的控制器范围内定义,因此实际上并不需要这样做。
看到你如何不将lastId
或lastTImestamp
暴露给this
或 $scope
,这让我相信您正在调用这样的方法:
<button ng-click="loadOlderAlbums()">Load more albums</button>
在这种情况下,lastId
和lastTimestamp
从未传递到您的$ scope函数,它只是不起作用。
这样的事情应该这样做:
$scope.loadOlderAlbums = function() {
ContentFactory.getOlderAlbums(lastId, lastTimestamp).then(function(albums){
$scope.albums = $scope.albums.concat(albums);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
现在,您不必将lastId或lastTimestamp传递到您的函数中(正如您之前所要求的那样)。
如果您某些在开始滚动之前getAlbums()
调用已经被解雇,则以下情况应该正常(编辑一堆代码以突出显示)要点):
var lastId, lastTimeStamp:
getAlbums().then(function (res) {
lastId = res.lastId;
lastTimeStamp = res.lastTimeStamp;
});
/** Later, called from the view **/
function loadOlderAlbums () { // <-- Kill the arguments.
$http.get('path' + lastId + lastTimeStamp).then(function (res) {
/** woop woop! **/
});
}
否则 - 您需要为该方案设置故障保护。你可以选择另一个承诺,或者是非常简单的东西,暂时可以排除它:
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 **/
}
通过在其中添加throw
语句,您可以验证是否存在:
lastId
和lastTimeStamp
变量的存储(通过getAlbums)/用法(通过loadOlderAlbums)中的竞争条件。因为你正在使用Ionic - 它反过来使用ui-router;您可以将getAlbums
的呼叫移动到resolve block,并确保在开始滚动之前将数据加载到控制器中。
这看起来像是:
.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
};
});
}
}
}
现在,只要您尝试导航到所述状态,解析对象将在调用控制器之前获取其内容。因此,您可以确保在用户开始在PicturesCtrl
范围内滚动之前存在数据,并且loadMoreAlbums
所需的参数将在那里。
您的PicturesCtrl
现在看起来像是:
.controller('PicturesCtrl', function ($scope, $ionicLoading, ContentFactory, preloadedAlbums) {
$scope.albums = preloadedAlbums;
var lastId = preloadedAlbums.lastId;
var lastTimeStamp = preloadedAlbums.lastTimeStamp;
/** etc **/
});
我会尝试第一个建议(使用throw
),以确保getAlbums
承诺未解决导致您的问题。然后我会考虑转移到resolve
块。
如果这不能解决问题的原因,我会用debugger
来推动代码库,并从头到尾逐步完成以验证实际<是什么< / em>继续。