因为在前一篇文章中写过,这里就不重复了。参考下面这个连接:
ASP.NET WebAPI 双向token实现对接小程序登陆逻辑
下面这个连接是参考资料,直接参考这一篇就明白怎么设置请求头
jquery ajax 设置请求头header参数php
如上图红色框所示,引用同一js文件中的函数不像普通js调用,须要加上下面代码段加粗部分。(不知道在代码段里面为何不显示粗体了,就是**这里)html
onLoad: function (options) { **var that=this;** **this.loadList();** }, **loadList**:function(e){ wx.request({ url: app.globalData.apiurl + '/api/NoUploadBackBill', data: { mobile: app.globalData.phone, }, header: { 'content-type': 'application/json', // 默认值 'Authorization': "BasicAuth " + util.getToken() }, success(res) { console.log(res.data.length); } }) },
个人需求是显示返回的列表数据,页面须要分条显示。一般是要用js遍历,但在小程序里面,只须要返回数据集,在wxml页面用wx:for绑定数组便可显示。以下图所示,使用wx:for后没有提供wx:key会报一个warning,在这小节后面第一个连接是官方的文档,里面有提到【如不提供 wx:key,会报一个 warning, 若是明确知道该列表是静态,或者没必要关注其顺序,能够选择忽略。】
前端
wxml页面: <view wx:for="{{newBillList}}" wx:key="*this" class="list"></view>
该数组要在js文件的data内声明。jquery
js文件: 声明: data: { newBillList: [], //要显示的列表以及搜索操做后的列表 }, 赋值: loadList: function(e) { //发起请求,根据手机号加载未上传回单 wx.request({ url: app.globalData.apiurl + '/api/NoUploadBackBill/Loading', data: { mobile: app.globalData.phone, }, header: { 'content-type': 'application/json', // 默认值 }, success: res => { if (res.data.length > 0) { var list = []; for (var i = 0; i < res.data.length; i++) { res.data[i].ImageList = []; list.push(res.data[i]); } this.setData({ billList: list, **newBillList: list** }); } }, fail(res) { console.log("loadList fail:" + res.data); } }) }
小程序for循环web
小程序的js里面和通用的js传参同样,经过全局变量传递,或函数参数传递。ajax
//调用处理列表图片的方法 this.addImageList(1, 0); //从新处理数据,把图片列表加入 addImageList: function (type, count) {}
Page.prototype.setData(Object data, Function callback)数据库
在微信小程序中,通常经过this.setData来修改值。好比在函数里面修改数据,以下代码段所示:search要在data内初始化json
searchinput: function (e) {//查询输入框赋值 this.setData({ search: e.detail.value }) }
可是,当经过wx.request请求数据成功后绑定数据却出现this.setData is not a function的错误。
小程序
//发起请求,根据手机号加载未上传回单 wx.request({ url: app.globalData.apiurl + '/api/NoUploadBackBill', data: { mobile: app.globalData.phone, }, header: { 'content-type': 'application/json', // 默认值 }, success(res) { console.log(res.data); if(res.data.length>0){ this.setData({ billList: res.data }); } },fail(res){ console.log("fail"+res); } })
为何会出现这个error呢,我当时百思不得其解,也没有想到做用域这一层,是查找资料才解决该问题。
缘由是由于:由于this做用域指向问题 ,success函数实际是一个闭包 , 没法直接经过this来setData。
第一种方法: var that=this; this.setData({billList:res.Data});
第二种方法: success:res=>{ this.setData({billList:res.data}) }
具体缘由要参考这个连接
参考资料:微信小程序中this指向做用域问题this.setData is not a function报错
隐藏和显示,必定明白是用样式控制了。并且是在JS控制样式,代码段以下:
wxml页面: <view wx:for="{{billList}}" wx:key="*this" class="list" style="display:{{billdisplay}};" >
/** * 页面的初始数据 */ data: { **billdisplay**:'block',//回单列表是否显示 **searchdisplay**:'none'//查询列表是否显示 }, searchList:function(e){//搜索事件 var _this=this; //设置首次加载的回单列表隐藏,显示查询的列表 _this.setData({ billdisplay:'none', searchdisplay:'block' }); }
后记:当时由于想法不完整,因此把显示数据列表用两个View表示,用样式控制,但其实这两个View显示的内容是同样的。后来经过初始化两个数组,一个显示查询后的列表,一个是原始数据的列表,用两个数组经过在使用中从新push数据,这样解决了用两个view处理的冗余办法。这个作法在第12点。
在小程序里面,在data里初始化的变量是没法直接push的。要在使用的时候另外声明变量,push,最后再赋值。以下代码段加粗部分(即有**的部分):
//从新处理数据,把图片列表加入 addImageList: function (type, count) { var that = this; **var listArr = [];//声明一个可操做变量数组** for (let i = 0; i < this.data.newBillList.length; i++) { if (this.data.shipmentid == this.data.newBillList[i].ShipmetId) { //累加上传的回单 var cnt = this.data.newBillList[i].DocumentsCnt; count=count+cnt; let row = { ShipmetId: this.data.newBillList[i].ShipmetId, EarliestPickTime: this.data.newBillList[i].EarliestPickTime, FromAddress: this.data.newBillList[i].FromAddress, ToAddress: this.data.newBillList[i].ToAddress, DriverName: this.data.newBillList[i].DriverName, LicenseNumber: this.data.newBillList[i].LicenseNumber, DocumentsCnt: type == 1 ? this.data.newBillList[i].DocumentsCnt : count, ImageList:this.data.imageListArr } **listArr.push(row);** } else { let row = this.data.newBillList[i]; **listArr.push(row);** } } //赋值 that.setData({ //显示列表 **newBillList: listArr** }); },
参考资料
小程序push数组报错解决办法
wxml页面: <button catchtap="removeImg" class="button_img" type="default" id="{{image}}" data-shipmentid="{{item.ShipmetId}}">移除</button>
js页面: //直接获取ID var viewId = e.target.id; console.log(viewId); //获取data-shipmentid var shipmentid=e.target.dataset.shipmentid; console.log(shipmentid);
原本想贴一下官方的api有关e.target以及e.current.target的资料,可是突然搜索不出来.....
这里比较简单,又易理解,直接贴官方的代码
<view>{{"hello" + name}}</view>
Page({ data:{ name: 'MINA' } })
如上图所示,我当前开发中的文件目录以下:
pages/business/nouploadbackbill/nouploadbackbill,
我在js文件中引用util.js的时候,我觉得能够这样的:
const util = require('../../utils/util.js')
可是,实际上彷佛要根据当前开发文件的目录结构引用
//引用 const util = require('../../../utils/util.js')
不知道是否是这样理解,若有误导或错误请指正批评~
没有remove,无法remove,只能经过操做数组处理。代码段参考第6点以及第12点
当时的问题是这样的,由于有一个view有id,而后view里有一个button,这个button事件须要取到view的id进行移除操做,须要标识是移除哪个view。
可是后现发现,view能够不用给id属性,button能够直接给id属性,直接用它本身的id值判断就能够操做。
代码参考第7点。
当时我之前在app.json文件配置的都是主页。主页里面跳转的页面没必要配置。直到报错才知道全部页面都要放在app.json里面配置。否则运行的时候会报not in app.json。以下图所示:
由于显示列表里面还有一个图片列表的数组,该列表有一个上传图片和移除图片操做,上传图片就把图片push到这个图片数组,而后从新push列表显示,移除也同样,把要移除的图片从列表里排除,从新push列表显示。
如下这段代码很是重要!由于正是看到了如下这段代码,我遇到的难题得以解决,感恩碰见,哈哈
因为这个连接是在小程序社区看到的,因此两个连接都贴出来,参考连接以下:
for (var i = 0; i < this.data.newBillList.length; i++) { if (e.target.dataset.id == this.data.newBillList[i].shipmentid) { newBillList[i] = { id: this.data.newBillList[i].id, price: this.data.newBillList[i], one2one: this.data.newBillList[i], } } else { txtArray1[i] = { id: this.data.liuliangItems[i].id, changeColor: false, price: this.data.liuliangItems[i].price, name: this.data.liuliangItems[i].name, one2one: this.data.liuliangItems[i].one2one } } }
小技巧系列
微信小程序点击button或view后选中其它反选
个人数据有三次循环量,由于在从一个循环列表里面操做两个循环。暂且说它是复合循环吧。当时困我好多天的难题用如下这段代码解决,快夸我~哈哈
//移除图片,按id移除 removeImg: function(e) { var that = this; var listArr = []; var imgArr = []; for (var i = 0; i < this.data.newBillList.length; i++) { if (e.target.dataset.shipmentid == this.data.newBillList[i].ShipmetId) { //相等的当前选中的数据,移除列表的图片的须要从新组合数据 for (var j = 0; j < this.data.newBillList[i].ImageList.length; j++) { //第一种写法 if (e.target.id != this.data.newBillList[i].ImageList[j]) { //相等的值是要移除的值,不做处理 imgArr.push(this.data.newBillList[i].ImageList[j]); //从新push图片 } //第二种写法,es6的写法 //let id = e.target.id; //this.data.newBillList[i].ImageList[j].splice(id,1);//删除 //splice(index,count) 第一个参数是索引,第二个参数是删除的个数 } //把数据从新push var row = { ShipmetId: this.data.newBillList[i].ShipmetId, EarliestPickTime: this.data.newBillList[i].EarliestPickTime, FromAddress: this.data.newBillList[i].FromAddress, ToAddress: this.data.newBillList[i].ToAddress, DriverName: this.data.newBillList[i].DriverName, LicenseNumber: this.data.newBillList[i].LicenseNumber, DocumentsCnt: this.data.newBillList[i].DocumentsCnt, ImageList: imgArr } listArr.push(row); } else { //数据不变的是不用处理的列表块,直接push var row = this.data.newBillList[i]; listArr.push(row); } }
这一部分被我形容是第二难题。(固然,是针对我在本身当前开发的功能里面~)
这里分为几个部分:
wx.chooseImage({ count: this.data.count[this.data.countIndex], sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: res => { // tempFilePath能够做为img标签的src属性显示图片 this.setData({ shipmentid: e.target.dataset.shipmentid, imageListArr: res.tempFilePaths }) //调用处理列表图片的方法 this.addImageList(1, 0);//该函数完整代码在第6点 }, fail: function(data) { wx.showToast({ title: "选择图片出错", icon: "none", duration: 1000 }); } });
//预览图片 previewImage: function(e) { let current = e.target.dataset.src; let imageList = []; for (let i = 0; i < this.data.newBillList.length; i++) { if (e.target.dataset.shipmentid == this.data.newBillList[i].ShipmetId) { imageList = this.data.newBillList[i].ImageList; } wx.previewImage({ current: current, //当前显示图片的连接 urls: imageList //须要预览的图片连接列表 }) } },
这里要说一下,我这边的需求是先把图片上传到开发者服务器,而后再从开发者服务器把图片读取保存到另外一个系统所在的服务器上。读取图片的时候不用下载图片,我上传图片的时候会在数据库一个表保存图片的相关信息,列表id,图片名称,在开发者服务器的所在路径等一些相关用到的字段。
第一步:先上传图片到开发者服务器,客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data
//上传图片,将本地资源上传到开发者服务器 uploadImage: function(e) { var that = this; that.setData({ shipmentid: e.target.dataset.shipmentid }); var listArr = []; var uploadImgCount = 0; var uploadArr = []; var imgLength = 0; for (var i = 0; i < this.data.newBillList.length; i++) { if (e.target.dataset.shipmentid == this.data.newBillList[i].ShipmetId) { imgLength = this.data.newBillList[i].ImageList.length; var index = i; console.log("列表的待上传的回单数:" + imgLength); if (imgLength < 1) { wx.showToast({ title: '没有可上传的回单', icon: 'none', mask: true, duration: 1000 }); var row = this.data.newBillList[i]; listArr.push(row); } else { //启动上传等待中... wx.showToast({ title: '正在上传...', icon: 'loading', mask: true, duration: 10000 }); //遍历图片列表上传 for (var j = 0; j < this.data.newBillList[i].ImageList.length; j++) { //记录当前列表的索引,由于到了success里就获取不到啦 var index = i; //上传图片到开发者服务器 wx.uploadFile({ url: app.globalData.apiurl + '/api/NoUploadBackBill/PostImageFile', filePath: this.data.newBillList[i].ImageList[j], //要上传文件资源的路径 name: 'image', // 这里的具体值,要与后台保持一致 header: { 'content-type': 'multipart/form-data', 'Authorization': "BasicAuth " + util.getToken() }, formData: { //HTTP 请求中其余额外的 form data 'shipmentid': this.data.shipmentid, 'imgIndex': j //上传的图片编号(后台提供给前端判断图片是否所有上传完) }, success: res => { //console.log("res:"+res.data); uploadImgCount++; uploadArr.push(res.data); //判断是否上传完毕 if (uploadImgCount == imgLength) { //显示数据,调用处理列表图片的方法,只修改所选运单的回单数便可 this.addImageList(2, uploadImgCount); //保存操做的列表数到TMS数据表 let row = { ShipmetId: this.data.newBillList[index].ShipmetId, EarliestPickTime: this.data.newBillList[index].EarliestPickTime, FromAddress: this.data.newBillList[index].FromAddress, ToAddress: this.data.newBillList[index].ToAddress, DriverName: this.data.newBillList[index].DriverName, LicenseNumber: this.data.newBillList[index].LicenseNumber, DocumentsCnt: uploadImgCount, ImageList: uploadArr } this.setData({ saveImageList: row }); //保存图片到TMS this.saveImage(); } }, fail: res => { console.log("uploadImage fail:" + res); wx.hideToast(); wx.showModal({ title: '错误提示', content: '上传图片失败', showCancel: false, success: function(res) {} }); } }); } } } } }
这里你们必定很关心个人后台代码是如何编写的,我是参考第一个连接作的。
第二步:把图片从开发者服务器读取并保存到另外一个服务器
这里当时由于POST数据以及'content-type',还有JSON.stringify也卡住了很久(知识点不扎实)
//保存图片 saveImage: function(e) { //console.log("新json字符串:" + JSON.stringify(this.data.saveImageList)); wx.request({ url: app.globalData.apiurl + '/api/NoUploadBackBill/SaveImageFile', data: JSON.stringify(this.data.saveImageList), header: { 'content-type': 'application/json', 'Authorization': "BasicAuth " + util.getToken() }, method: "POST", success: res => { console.log(" POST success:" + res.data.Message); if (res.data.Code == "0") { wx.showToast({ title: '上传成功', icon: 'none', mask: true, duration: 2000 }); } else { wx.showToast({ title: '上传图片到服务器失败:' + res.data.Message, icon: 'none', mask: true, duration: 2000 }); } }, fail: res => { console.log("saveImage fail:" + res.data); } }); },
这里你们必定也会关心数据的转换,这里贴一下后台代码:
//接收参数为dynamic类型 public IHttpActionResult SaveImageFile(dynamic obj){ var s = JsonConvert.SerializeObject(obj); //实例化一个可以序列化数据的类 JavaScriptSerializer js = new JavaScriptSerializer(); //将json数据转化为对象类型 var entity = js.Deserialize<NoUploadBackBillModel>(s); }
还有数据读取以及保存,这里使用文件流FileStream处理,从图片转换为二进制流读取,这里是调用web service处理的。具体代码不在我这边,就没有办法贴出来啦~
参考连接:
WebAPI 接口参数
找到了与该请求匹配的多个操做的解决办法
WebApi 找到了与该请求匹配的多个操做
WebAPI post传递参数二、实体做为参数
这个rpx我原来不知道是微信小程序推出了新尺寸单位。直到我作完功能测试发现没有自适应。由于我在里面惯性使用了px和em。后来看这个参考连接就所有改过来了,而后页面在不一样的设备不会溢出啦。参考连接以下:
最后,想说所遇到的问题点几乎都通过查阅资料解决。在知识红利的时代,你们无私分享本身的所学,在此很是感谢分享开发总结的伙伴。诚挚感谢!