[ionic开源项目教程]

时间:2021-03-30 08:54:01

[ionic开源项目教程] - 第8讲  根据菜单分类加载数据(重要)

[效果图]

[ionic开源项目教程]

 

注意

今天遇到一个比较棘手的问题,就是左右滑动菜单的设计不合理性,所以tab1.html对应的视图层和controller层都有所改动,最关键最核心的代码在service层,可能会有点不好理解,我会尽量讲明白。

1.tab1.html的要做一些调整: 这里我把tab1.html的完整代码贴出来,有以下几点改动

  • 1. ion-content:内容标签的位置放到了ion-slide内层和list外层,这样做的目的是解决多个滑动列表不相互干扰。
  • 2. slide.items:对list的数据源做了一层包装,这样做的目的是多个列表的数据不相互干扰。
  • 3. doRefresh下拉刷新和loadMore上拉加载和list的数据源items一样也做了一层包装。

<ion-view view-title="健康">
<ion-slide-box show-pager="false" on-slide-changed="slideChanged($index)">
<ion-slide ng-repeat="slide in slides">
<ion-content>
<ion-refresher pulling-text="下拉刷新" on-refresh="slide.doRefresh()"></ion-refresher>
<div class="list has-header">
<a ng-repeat="item in slide.items" class="item item-thumbnail-right item-text-wrap" href="#">
<img ng-src="{{imgUrl+item.img}}" width="30" height="30" alt="">
<h3>{{item.title}}</h3>
<p>{{item.description | substring:item.description}}</p>
</a>
</div>
<ion-infinite-scroll ng-if="!slide.isload" on-infinite="slide.loadMore()" distance="1%">
</ion-infinite-scroll>
</ion-content>
</ion-slide>
</ion-slide-box>
<ion-tabs class="tabs-striped tabs-top">
<ion-tab ng-repeat="item in tabs" on-select="selectedTab($index)" title="{{item.name}}"></ion-tab>
</ion-tabs>
</ion-view>

2.controller.js层Tab1Ctrl的实现

需要注意的地方:

  • 1.此次controller的改动的代码比较少,下拉刷新doRefresh和上拉加载loadMore都放到了service层。

  • 2.使用了ion-infinite-scroll标签后,controller页面初始化的时候会自动触发loadMore函数,但在android平台这个函数不会触发,所以做了判断。

.controller('Tab1Ctrl', function ($scope, $rootScope, $timeout, Tab1Service, $ionicSlideBoxDelegate, $ionicTabsDelegate) {
$rootScope.imgUrl
= server.imgUrl;

var classify = Tab1Service.getClassify()
$scope.slides
= classify;
$scope.tabs
= classify;

var getData = function (index) {
var c = classify[index];
// 安卓平台不会自动触发加载
if (ionic.Platform.isAndroid()) {
c.doRefresh();
}
// 初始化数据,和回调函数
c.isload = false;
c.callback
= function () {
$scope.$broadcast(
'scroll.refreshComplete');
$scope.$broadcast(
'scroll.infiniteScrollComplete');
}
}
getData(
0);

$scope.slideChanged
= function (index) {
getData(index);
//这里使用instances[1]的原因是视图中有两个tabs
$ionicTabsDelegate._instances[1].select(index);
};

$scope.$on(
'$ionicView.afterEnter', function () {
//等待视图加载完成的时候默认选中第一个菜单
$ionicTabsDelegate._instances[1].select($ionicSlideBoxDelegate.currentIndex());
});

$scope.selectedTab
= function (index) {
//滑动的索引和速度
$ionicSlideBoxDelegate.slide(index)
}

3.最难理解的service层

service层对不同的分类做了函数封装。每个分类都有自己的数据源items[]、doRefresh(下拉加载)、loadMore(加载更多),各个分类的数据加载都互不影响。视图层是直接通过controller为载体调用的service的函数。下面介绍下各个属性的说明:

  • name:菜单名
  • isload:是否加载
  • url:接口
  • page:页数
  • row:每页请求的条数(暂时没用到,这里做为备用参数),现在的页数都是用的全局配置config.js中的settings.rows
  • items:数据列表
  • loadMore:上拉加载更多 。
  • doRefresh:下拉刷新。
  • callback:回掉函数,在loadMore和doRefresh操作完成都会调用该函数。

.service('Tab1Service', function ($http) {
this.getClassify = function () {
return [
{
name:
'健康资讯', isload: true, url: server.domain + '/info/list',
page:
1, rows: 20,
items: [],
loadMore:
function () {
$
this = this;
console.log(
"正在加载更多数据..." + this.page);
$http.get(
this.url + "?page=" + this.page + "&rows=" + settings.rows).success(function (response) {
$
this.items = $this.items.concat(response.tngou);
$
this.page++;
$
this.callback();
});
},
doRefresh:
function () {
$
this = this;
console.log(
"正在执行refresh操作...");
$http.get(
this.url + "?page=1&rows=" + settings.rows).success(function (response) {
$
this.page = 2;
$
this.items = response.tngou;
$
this.callback();
});
},
callback:
function () {
//回掉函数
}
},
{
name:
'健康知识', isload: true, url: server.domain + '/lore/list',
page:
1, rows: 20,
items: [],
loadMore:
function () {
$
this = this;
console.log(
"正在加载更多数据..." + this.page);
$http.get(
this.url + "?page=" + this.page + "&rows=" + settings.rows).success(function (response) {
$
this.items = $this.items.concat(response.tngou);
$
this.page++;
$
this.callback();
});
},
doRefresh:
function () {
$
this = this;
console.log(
"正在执行refresh操作...");
$http.get(
this.url + "?page=1&rows=" + settings.rows).success(function (response) {
$
this.page = 2;
$
this.items = response.tngou
$
this.callback();
});
},
callback:
function () {
//回掉函数
}
},
{
name:
'健康问答', isload: true, url: server.domain + '/ask/list',
page:
1, rows: 20,
items: [],
loadMore:
function () {
$
this = this;
console.log(
"正在加载更多数据..." + this.page);
$http.get(
this.url + "?page=" + this.page + "&rows=" + settings.rows).success(function (response) {
$
this.items = $this.items.concat(response.tngou);
$
this.page++;
$
this.callback();
});
},
doRefresh:
function () {
$
this = this;
console.log(
"正在执行refresh操作...");
$http.get(
this.url + "?page=1&rows=" + settings.rows).success(function (response) {
$
this.page = 2;
$
this.items = response.tngou
$
this.callback();
});
},
callback:
function () {
//回掉函数
}
}
]
}
})

4.难点

  • 搞清楚视图层的包含关系
  • 对service层代码的理解

有什么不理解的地方欢迎加入 [Tonge移动开发交流群] 群号:111055535。

完!