微信小程序踩坑笔记

Author Avatar
julytian 4月 06, 2017
  • 在其它设备中阅读本文章

远程图片返回404处理

当网络请求图片服务器返回404时,image 返回空白结果,影响美观,希望和网页一样出错则显示默认占位图。

效果如下:

占位图

image 组件有个API表示:

当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: ‘something wrong’}

所以,我们可以在 组件上绑定 binderror, 大致如下:

1
<image class="list-pic" style="height: {{windowW/2*1.35}}px;" src="{{item.PicUrl}}" binderror="onImageError" data-err-img="searchResults[{{index}}].PicUrl"></image>

事件处理思路大致如下:

当发生错误时调用 binderror 事件函数, 通过 data-* 获取到默认占位图路径,然后重新设置 image 的 url

通过dataset属性将image组件的src变量值存入。binderror事件通过获取属性变量值改变data的数据。当然这个有个弊端,就是image组件的src是动态的值而不能是直接指向某张图片的情况下。

上面是针对单一图片出现错误进行处理,当时我们一般都是一个 结果数组列表的形式,这个时候 binderror 事件是在图片错误的时候才会调用该事件的,那么在事件中实际上是通过 data-*获取了list中当前错误的对象图片在进行setData 的。

多个image报错处理代码如下:

1
<image class="list-pic" style="height: {{windowW/2*1.35}}px;" src="{{item.PicUrl}}" binderror="onImageError" data-err-img="searchResults[{{index}}].PicUrl"></image>
1
2
3
4
5
6
7
onImageError: function(ev){
var _errImg=ev.target.dataset.errImg;
var _errObj={};
_errObj[_errImg]="http://i2.mbscss.com/img/moonbasa/2014/jue/M10_27_203039.jpg";
console.log( ev.detail.errMsg+"----" + "----" +_errImg );
that.setData(_errObj);
}

但是这样存在一个情况就是每个页面都写这个程序不是很臃肿,那么我们考虑怎么把他写入到模块js文件里面呢?

解决方案::先把 this对象传入到js函数里面,就可以直接修改外面的data数据了。具体函数如下:

1
2
3
4
5
6
7
8
9
10
11
//远程图片no found情况下指引
function errImgFun(ev, that){
var _errImg=ev.target.dataset.errImg;
var _errObj={};
_errObj[_errImg]="http://i2.mbscss.com/img/moonbasa/2014/jue/M10_27_203039.jpg";
console.log( ev.detail.errMsg+"----" + "----" +_errImg );
that.setData(_errObj);
}
module.exports = {
errImgFun: errImgFun
}

xx.js 里面引入调用:

1
2
3
4
5
6
7
// 处理图片加载404问题
var errorImage = require('../../utils/errorImage.js');
// 远程图片加载404显示默认图
onImageError: function (ev) {
var _that=this;
errorImage.errImgFun(ev, _that);
}

scroll-view 组件在 tabar页面中不同系统下高度不一致的诡异问题

如上图,我们有个需求是这样的,左边点击分类,右边更新,并且如果数据多可以滚动。当初考虑方法是采用左右二个 scroll-view组件做,因为它是可滚动视图区域,可以根据 设备的 系统信息API 获取到屏幕的高度设置 scroll-view 的高度,跟随设备屏幕高度自适应。

1
2
3
4
5
6
7
8
9
10
11
wx.getSystemInfo({
success: function(res) {
console.log(res.model)
console.log(res.pixelRatio)
console.log(res.windowWidth)
console.log(res.windowHeight)
console.log(res.language)
console.log(res.version)
console.log(res.platform)
}
})

获取到设备的屏幕高度,从而设置 scroll-view 的高度。

1
<scroll-view scroll-y="true" style="height:{{deviceHeight}}px" class="left_tabbar_list"></scroll-view>

理论上,这样设置是没有问题的,在非 tabar 页面设置高度, IOS和安卓系统下都是没问题的,但是在 tabar页面上,在 iOS 下就会出现下面的 tabar遮住了滚动高度,出现偏差,滚动无法滚动完全出来。

网上查了相关资料也没有一个说法,我不断测试发现 IOS 下获取的屏幕高度把 tabar 的高度也计算进来了,tabbar的高度是 50px , 所以,我们需要根据不同设备系统计算高度,大致方法如下:

IOS下获取到设备的屏幕高度,然后减去 tabar 的高度,安卓则不变

1
2
3
4
5
6
7
8
9
wx.getSystemInfo({
success: (res) => {
that.setData({
deviceWidth: res.windowWidth,
deviceHeight: res.windowHeight-50+'px',
platform: res.platform
});
}
});
1
<scroll-view scroll-y="true" style="height:{{platform=='ios'?deviceHeight:'100%'}}" class="left_tabbar_list"></scroll-view>

经过测试,IOS和安卓下面都没有问题了。

小程序跨页面通信处理

注意:为了不让用户在使用小程序时造成困扰,我们规定页面路径只能是五层,请尽量避免多层级的交互方式。

微信小程序对页面跳转做了严格限制处理。但是有时,需求超过了5层,并且需要跨页面来回跳转处理数据,我这边的小程序就涉及到这样一个要求:搜索页跳到筛选页,做完处理跳回搜索页查询,来回跨页面跳转,所以筛选页面不能使用 navigateTo,因为来回跳转容易出现超过5层,出bug,无法继续跳转

解决办法,筛选页面使用 跨页面通信,直接 navigateBack返回,避免再次出现超过5层跳转情况。

这里,我们使用 github 上个一个通信操作库,地址, 里面有基本用法.

问题出处情况如下:搜索跳到筛选,又跳回来:

搜索

筛选

部分代码处理如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 跨页面通信方法
var WxNotificationCenter = require('../../utils/WxNotificationCenter.js');
// 搜索页
wx.navigateTo({
url: '../filtrate/filtrate?sourcefrom=search&keyword=' + that.data.inputVal + '&order=' + that.data.order + '&orderby=' + that.data.orderby
});
// 筛选页
// 向上一页发送一个通知
WxNotificationCenter.postNotificationName('filtrateNotification', filtrateUrl);
wx.navigateBack();
// 搜索页接收通知
// 从筛选跳转回来的操作
WxNotificationCenter.addNotification('filtrateNotification', that.onFiltrateNotification, that);

注意: 新版小程序的 wx.redirectTo(OBJECT) 可以回传参数了,这样就可以避免跨页面传参了,只需要在参数做个判断来自哪个页面的信息就可以了!!