坑一、new Bmob.File的第二个参数并非String类型,而是将String包成Array
例如以下写法才是正确上传,哪怕只传一张图片
var file = new Bmob.File(name, [tempFilePaths[0]]);
如果写成这样,
var file = new Bmob.File(name, tempFilePaths[0]);
将报uploadFile:fail createUploadTask:fail file not found
翻看了bmob.js源码,在2792行找到如下代码
if (extension == "mp4") {
data = data;
}
else {
data = data[0];
}
这才真相大白,给了mp4以特殊照顾,其余情况由bmob.js帮你取出[0]第一元素,这才导致了要手工多包一层Array。
坑二、将File类型存回对象时,报Converting circular structure to JSON
循环引用。
在更换头像的场景里,当上传了一个新的Bmob.File后,本打算这么写
seller.set('logo', logo);
that.setData({
seller: seller
});
不料控制台报了错
看出错描述是无限死循环了
解决的方法是,不指望更新seller这个对象来做数据双向绑定了,另起String类型的属性new_logo到data中
that.setData({
new_logo: logo.url()
});
然后在wxml中三目判断是新头像还是旧头像
<image class="userinfo-avatar" src="{{new_logo ? new_logo : seller.logo.url}}" background-size="cover" bindtap="chooseImage" mode="aspectFill"></image>
后记,由于实在觉得这么写法过于ugly,向Magic大神请教,于是有了下面的解决方案
file.save().then(function(logo){
// 先取出原seller对象
query.get("TrgsNNNj", {
success: function (result) {
//查出seller对象并设logo属性
result.set('logo', logo);
// 再次存回
result.save().then(function (seller) {
// 再次存出
query.get(seller.id).then(function (new_seller) {
that.setData({
seller: new_seller
});
});
}, function (error) {
console.log(error);
});
},
error: function (object, error) {
}
});
},function(error){
console.log(error);
})
这时候wxml渲染变干净了
<image class="userinfo-avatar" src="{{seller.logo.url}}" background-size="cover" bindtap="chooseImage" mode="aspectFill"></image>
其中的原因是,save()回调得到的object与get()得到的不吻合,所以拿save()得到的objectId再get查询一次,再丢给wxml,如此反复的save()与get()两次,就能顺利渲染了。
源码下载:关注公众号【黄秀杰】,回复112。本文代码涉及代码位于admin-dev分支下的shop文件夹。