您的位置:首页 > 移动开发 > 微信开发

[解读小程序]灵犀新闻客户端

2016-09-28 11:57 357 查看

[解读小程序]灵犀新闻客户端

分析的程序来源:

https://my.oschina.net/u/1012086/blog/751455

作者: 黄秀杰

OsChina地址: http://git.oschina.net/dotton/news/tree/master

其实该代码的作者的博文里面已经写的很清楚了. 我只是站在一个分析者的角度学习一下.

效果图



已知存在的问题

列表一次性加载大概40条数据. 使用微信IDE调试时, 基本上处于假死状态. 未完成分页加载.

头部的类似于Android中的ViewPager的swiper, 一次加载了30条数据. 显示的指示点过多. 而且未能根据屏幕大小将图片正确铺满.

列表中前面的图片用wxss限制了width和height, 但是还是会出现大小不一致的情况.

点击列表进入的详情页. 因为详情直接是一个url,而小程序中并没有提供类似于Android中的WebView一样的控件, 所以功能尚未完成.

有些小问题我已经反馈给了作者. 坐等作者更新吧.

app.json

"pages":[
"pages/index/index",
"pages/detail/detail"
]


从pages数组看出, 程序只有两个页面.

新闻列表页 index

从页面上看, 新闻列表头部是一个swiper, 底下就是之前讲过的列表渲染. 我们从index.wxml开始解读.

index.wxml

<swiper indicator-dots="true"
autoplay="true" interval="5000" duration="1000">
<block wx:for="{{topNews}}">
<swiper-item>
<image src="{{item.thumbnail_pic_s02}}" mode="aspectFill" class="slide-image" width="375" height="250"/>
</swiper-item>
</block>
</swiper>


这个是swiper的用法. 微信已经帮你集成好了轮播图组件. 文档-swiper

有几个比较常用的属性indicator-dots(是否显示指示点),autoplay(是否自动播放),interval(事件间隔),bindchange(滑动change事件).

swiper有个特别要注意的地方就是中只可放置组件,其他节点会被自动删除。

代码中使用了block wx:for的列表渲染结构. 文档-列表渲染

利用数据绑定topNews数组, 每个swiper-item中显示一张图片.

虽然image设置了aspectFill属性,但是在实际调试看起来并没有铺满.

底下就是列表项了. 经过之前文章的讲解, 这个很容易看懂.

<view class="container news-list">
<block wx:for="{{techNews}}">
<view class="news-item" data-title="{{item.title}}" data-url="{{item.url}}" bindtap="bindViewTap">
<image src="{{item.thumbnail_pic_s}}" mode="aspectFill" class="list-image"/>
<view class="news-text">
<text class="news-title">{{item.title}}</text>
<view class="news-stamp">
<text>{{item.author_name}}</text>
<text>{{item.date}}</text>
</view>
</view>
</view>
</block>
</view>


这样的布局逻辑结构很清晰. 一个包裹所有item的view, 利用列表渲染生成多个item,每个item都包括左侧的一张图片还有标题和时间戳等.

不过我有一点比较好奇的是, 当显示的项目超过屏幕高度时, 显示出来的效果是可以滚动, 这里并没有添加srcoll-view. 这一点和Android好像不同.

这里面有两个属性data-title, data-url和事件处理有关,在讲解代码的时候再说.文档-事件

index.js

初始化数据

data: {
topNews:[], //顶部新闻
techNews:[] //列表新闻
},


页面加载时请求数据

onLoad: function () {
var that = this
// 访问聚合数据的网络接口-头条新闻
wx.request({
url: 'http://v.juhe.cn/toutiao/index',
data: {
type: 'topNews' ,
key: '482e213ca7520ff1a8ccbb262c90320a'
},
header: {
'Content-Type': 'application/json'
},
success: function(res) {
if (res.data.error_code == 0) {
that.setData({
topNews:res.data.result.data
})
} else {
console.log('获取失败');
}
}
})
// 访问聚合数据的网络接口-科技新闻
wx.request({
url: 'http://v.juhe.cn/toutiao/index',
data: {
type: 'keji' ,
key: '482e213ca7520ff1a8ccbb262c90320a'
},
header: {
'Content-Type': 'application/json'
},
success: function(res) {
if (res.data.error_code == 0) {
that.setData({
techNews:res.data.result.data
})
} else {
console.log('获取失败');
}
}
})
},


利用wx.request()发起请求. 这个看API就能懂. 文档-发起请求.

注意的是这里
var that=this
, 在success()中调用则是

that.setData({
techNews:res.data.result.data
})


一般而言,在Javascript中,this指向函数
执行时
的当前对象。所以不能使用this.setData(). 这一点和Android中this类似(在Activity的匿名内部类中使用this, 这个this表示匿名内部类的对象).

前面从wxml中看到每个item的view都bind了tap事件.

//事件处理函数
bindViewTap: function(event) {
wx.navigateTo({
url: '../detail/detail?title='+event.currentTarget.dataset.title+'&url='+event.currentTarget.dataset.url
})
},


bind事件绑定不会阻止冒泡事件向上冒泡. 事件对象event有两个重要的属性target和currentTarget. target表示触发事件的源组件, currentTarget表示事件绑定的当前组件. 文档-事件

currentTarget对象有一个dataset的属性. dataset属性允许在组件中自定义数据,这些数据将会通过事件传递给AppService。以data-开头,多个单词由连字符-链接.

我们之前看到的在item的view中写的属性data-title, data-url就是事件对象event中包含的dataset.

<view class="news-item" data-title="{{item.title}}" data-url="{{item.url}}" bindtap="bindViewTap">


也就是说当item的view触发tap事件时, 设置在view的data-title, data-url将封装到最终的事件对象event中. 这样我们在js中就可以获得这些值了.
event.currentTarget.dataset.title
event.currentTarget.dataset.url
.

wx.navigateTo({
url: '../detail/detail?title='+event.currentTarget.dataset.title+'&url='+event.currentTarget.dataset.url
})


这里利用导航的API进行页面间的跳转wx.navigateTo(). 文档-导航

从url的组成形式来看, 完全是http的那一套. 多个参数之间利用&链接.

新闻详情页 detail

这个页面其实是个半成品. 作者的原意是要显示一个网页的. 但是没有找到类似Android平台的webview控件, 所以基本上没有功能.

detail.js

Page({
data: {
title:'',
url:''
},
onLoad: function (options) {
this.setData({
title:options.title,
url:options.url
})
}
})


这里还是只讲一下如何获得从其他页面传过来的值的问题.

page的生命周期方法onLoad有个参数options. 我们可以直接从options中获得页面路由携带的参数.

目前作者的代码也就更新到这里. 暂时就讲解到这里.

the end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: