我正在尝试使用Ionic Framework构建一个IOS和Android应用程序,该应用程序具有带有Instagram api的Instagram Feed,显示所有由hashtag共享的照片(我将使用hashtag chocolat有一个例子)我想实现拉动刷新和无限滚动,所以基本上我会有一个按钮,一旦点击打开一个视图与instagram提要并拉取前10个结果,拉动刷新将尝试获得更新的结果,然后如果饲料滚动下来它会添加下一组结果(旧结果)。我一直在寻找,并且我已经构建了一些不按预期工作的东西。 我是离子,angularjs和javascript的新手开发者,所以我决定在这里发表我的问题。
所以这是我的代码:
通过http获取instagram json的工厂或服务:
app.factory('PhotoService', function($http){
var BASE_URL = "https://api.instagram.com/v1/tags/chocolat/media/recent?access_token=+++";
//access_token hidden for privacy reasons
var items = [];
var nextUrl = 0;
return {
GetFeed: function(){
return $http.get(BASE_URL+'&count=10').then(function(response){
items = response.data.data;
nextUrl = response.data.pagination.next_url;
return items;
});
},
GetNewPhotos: function(){
return $http.get(BASE_URL+'&count=2').then(function(response){
items = response.data.data;
return items;
});
},
GetOldPhotos: function(){
return $http.get(nextUrl).then(function(response){
items = response.data.data;
return items;
});
}
}
});
控制器:
app.controller('CivrInstagramController', function($scope, $timeout, PhotoService) {
$scope.items = [];
$scope.newItems = [];
PhotoService.GetFeed().then(function(items){
$scope.items = items;
});
$scope.doRefresh = function() {
if($scope.newItems.length > 0){
$scope.items = $scope.newItems.concat($scope.items);
//Stop the ion-refresher from spinning
$scope.$broadcast('scroll.refreshComplete');
$scope.newItems = [];
} else {
PhotoService.GetNewPhotos().then(function(items){
$scope.items = items.concat($scope.items);
//Stop the ion-refresher from spinning
$scope.$broadcast('scroll.refreshComplete');
});
}
};
$scope.loadMore = function(){
PhotoService.GetOldPhotos().then(function(items) {
$scope.items = $scope.items.concat(items);
$scope.$broadcast('scroll.infiniteScrollComplete');
});
};
});
观点:
<ion-view view-title="#Chocolat Photos!">
<ion-content>
<ion-refresher on-refresh="doRefresh()"></ion-refresher>
<div class="list card" ng-repeat="item in items track by item.id">
<div class="item item-avatar">
<img ng-src="{{item.user.profile_picture}}" ng- if="item.user.profile_picture.startsWith('https')">
<h2>{{item.user.full_name}}</h2>
<p><span am-time-ago="item.created_time" am-preprocess="unix"></span></p>
</div>
<div class="item item-body" >
<img ng-src="{{item.images.low_resolution.url}}" ng-if="item.images.low_resolution.url.startsWith('https')">
<p>
{{item.caption.text}}
</p>
</div>
</div>
<ion-infinite-scroll on-infinite="loadMore()" distance="5%"></ion-infinite- scroll>
</ion-content>
</ion-view>
PhotoService.GetFeed()运行正常,因为它正确填充前10张照片,但是,当我尝试无限滚动时,我收到错误:
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.
我正在使用track by item.id,你可以在视图中看到,所以我认为这意味着我使用 PhotoService.GetOldPhotos()一遍又一遍地获得相同的结果。至于 PhotoService.GetNewPhotos(),当有新数据要显示时,它会工作,但是当没有要获取的新数据时,它会在转发器中抛出相同的重复错误(没有#chocolat的新帖子) )
我做错了什么?任何人都可以给我一些建议吗?在此先感谢您的时间!这是我项目的plnkr ++ 链接,您可以在其中实际看到它正在尝试工作:\
++ 您可能需要在浏览器中启用跨源资源共享才能看到Feed正常工作。
EDIT1:几乎完成了!
所以经过一段漫长的时间和一些console.log()之后:p我能够通过标签得到一个Instagram feed并使其与离子拉动一起工作以刷新和离子无限滚动(我想是90%)但是我的代码仍然存在问题,因为每次滚动到最后一组项目时我都无法停止无限滚动和loadMore(),并且它们会尝试加载更多数据,因为最后一个nextUrl未定义但是instagram-api接受&amp; next_max_tag_id = undefined并再次获取最新结果,这会导致错误,因为ng-repeat中没有重复项,我不想再显示第一个结果。
我只需要在没有更多结果时停止loadMore和无限滚动,或者如果&amp; next_max_tag_id = undefined,或者两个数组中都有重复项(但我不认为这是推荐的性能)。所以这是我的项目的plnkr,谢谢你的时间!
我将标记更改为效果较差的内容,因此您可以实际看到错误而不必厌倦滚动:p
答案 0 :(得分:2)
我们分别解决了这个问题,但我想我也会在这里发布答案。主要变化是
min_tag_id
和max_tag_id
格式getOldPhotos()
方法,以便在没有next_max_tag_id
时自动返回一个空数组(从技术上讲,它会返回一个已经解析为空数组的不同承诺。)$scope.loadMore()
以检查空响应并设置标记以终止<ion-infinite-scroll>
请在此处查看完整的工作副本:http://plnkr.co/edit/LBW0pp?p=preview