部分代码来自:http://blog.csdn.net/qq_38125123/article/details/75043607
我主要是把静态的地址库文件改成动态从数据库读取,
以下是小程序的代码:
wxml:
<view>
<label class='xLab'>所在地区:</label>
<input class='xInp' maxlength="100" placeholder="" value='{{areaInfo}}' bindtap="selectDistrict" disabled='disabled' />
<image class='xSelectImage xSelectImage2' src='../../images/registered-select.png'></image>
</view>
<view class='container mask' style="display:{{display}}">
</view>
<view class="picker-view" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
<view style="height:10% ;width:95%;margin-top:10rpx">
<text catchtap="cityCancel">取消</text>
<text style="float: right" catchtap="citySure">确定</text>
</view>
<picker-view style="width: 100%; height: 300px;" bindchange="cityChange" value="{{value}}" wx:key="">
<picker-view-column>
<view wx:for="{{provinces}}" class="picker-item">
{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{citys}}" class="picker-item" wx:key="">
{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{areas}}" class="picker-item" wx:key="">
{{item.name}}</view>
</picker-view-column>
</picker-view>
</view>
wxss:
.picker-view {
width: 100%;
display: flex;
z-index:12;
background-color: #fff;
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0rpx;
left: 0rpx;
height: 40vh;
}
.picker-item {
line-height: 70rpx;
margin-left: 5rpx;
margin-right: 5rpx;
text-align: center;
}
.mask{
background-color: #000;
opacity: 0.2;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 10
}
JS:
var address = []//地区数据
/**
* 页面的初始数据
*/
data: {
animationAddressMenu: {},
addressMenuIsShow: false,
value: [0, 0, 0],
provinces: [],
citys: [],
areas: [],
province: '',
city: '',
area: '',
display: "none",
currentID: '',
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
var that = this;
// 初始化动画变量
var animation = wx.createAnimation({
duration: 500,
transformOrigin: "50% 50%",
timingFunction: 'ease',
})
that.animation = animation;
// 默认联动显示北京
address=wx.getStorage({
key: 'AllArea',
success: function(res) {
if(address == null){
that.getAllArea();
}
else{
that.setAllArea();
}
},
fail: function(res) {
that.getAllArea();
},
complete: function(res) {},
})
},
//获取地址库
getAllArea:function(){
var that= this;
wx.request({
url: app.globalData.url +'/api/Home/GetAllArea',
header: {
'content-type': 'application/json',
},
success: function (res) {
var result = res.data;
if (result.IsError == false) {
wx.setStorage({
key: 'AllArea',
data: result.Result,
});
address = result.Result;
that.setAllArea();
}
else {
wx.showToast({
title: code.Msg,
icon: 'success',
duration: 2000
})
}
},
fail: function (res) {
wx.showToast({
title: "网络错误",
icon: 'success',
duration: 2000
})
},
});
},
//设置默认地址信息
setAllArea:function(){
var id = address.provinces[0].id
this.setData({
provinces: address.provinces,
citys: address.citys[id],
areas: address.areas[address.citys[id][0].id],
})
},
// 点击所在地区弹出选择框
selectDistrict: function (e) {
var that = this
// 如果已经显示,不在执行显示动画
if (that.data.addressMenuIsShow) {
return
}
// 执行显示动画
that.startAddressAnimation(true)
},
// 执行动画
startAddressAnimation: function (isShow) {
var that = this
if (isShow) {
// vh是用来表示尺寸的单位,高度全屏是100vh
that.animation.translateY(0 + 'vh').step();
//显示遮罩层
that.setData({
display: "block"
})
} else {
that.animation.translateY(40 + 'vh').step();
//隐藏遮罩层
that.setData({
display: "none"
})
}
that.setData({
animationAddressMenu: that.animation.export(),
addressMenuIsShow: isShow,
})
},
// 点击地区选择取消按钮
cityCancel: function (e) {
this.startAddressAnimation(false)
},
// 点击地区选择确定按钮
citySure: function (e) {
var that = this
var city = that.data.city
var value = that.data.value
that.startAddressAnimation(false)
// 将选择的城市信息显示到输入框
var areaInfo = that.data.provinces[value[0]].name + ',' + that.data.citys[value[1]].name + ',' + that.data.areas[value[2]].name;
var id = that.data.areas[value[2]].id;
that.setData({
areaInfo: areaInfo,
currentID:id,
})
},
// 点击蒙版时取消组件的显示
hideCitySelected: function (e) {
this.startAddressAnimation(true)
},
// 处理省市县联动逻辑
cityChange: function (e) {
console.log(e)
var value = e.detail.value
var provinces = this.data.provinces
var citys = this.data.citys
var areas = this.data.areas
var provinceNum = value[0]
var cityNum = value[1]
var countyNum = value[2]
// 如果省份选择项和之前不一样,表示滑动了省份,此时市默认是省的第一组数据,
if (this.data.value[0] != provinceNum) {
var id = provinces[provinceNum].id
this.setData({
value: [provinceNum, 0, 0],
citys: address.citys[id],
areas: address.areas[address.citys[id][0].id],
})
} else if (this.data.value[1] != cityNum) {
// 滑动选择了第二项数据,即市,此时区显示省市对应的第一组数据
var id = citys[cityNum].id
this.setData({
value: [provinceNum, cityNum, 0],
areas: address.areas[citys[cityNum].id],
})
} else {
// 滑动选择了区
this.setData({
value: [provinceNum, cityNum, countyNum]
})
}
},
以下是后台(.Net)代码:
地址信息模型:
/// <summary>
/// 微信小程序所需的地址数据模型
/// </summary>
public class WxAreaModel
{
/// <summary>
/// 省份信息集合
/// </summary>
public List<wxProvince> provinces { get; set; }
/// <summary>
/// 城市信息集合
/// </summary>
public Dictionary<int, List<wxCity>> citys { get; set; }
/// <summary>
/// 区县信息集合
/// </summary>
public Dictionary<int, List<wxArea>> areas { get; set; }
}
/// <summary>
/// 省份信息
/// </summary>
public class wxProvince
{
/// <summary>
/// 省份名
/// </summary>
public string name { get; set; }
/// <summary>
/// 省份ID
/// </summary>
public int id { get; set; }
}
/// <summary>
/// 城市信息
/// </summary>
public class wxCity
{
/// <summary>
/// 所在省份名
/// </summary>
public string province { get; set; }
/// <summary>
/// 城市名
/// </summary>
public string name { get; set; }
/// <summary>
/// 城市ID
/// </summary>
public int id { get; set; }
}
/// <summary>
/// 区县信息
/// </summary>
public class wxArea
{
/// <summary>
/// 所在城市名
/// </summary>
public string city { get; set; }
/// <summary>
/// 区县名
/// </summary>
public string name { get; set; }
/// <summary>
/// 区县ID
/// </summary>
public int id { get; set; }
}
返回的json对象模型:
/// <summary>
/// Json返回信息实体
/// </summary>
public class ReturnResult
{
/// <summary>
/// 是否错误
/// </summary>
public bool IsError { get; set; }
/// <summary>
/// 错误消息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 正确结果
/// </summary>
public object Result { get; set; }
}
从数据库及缓存中读取地址信息:
/// <summary>
/// 用户在注册时,获取微信上显示的地址库(一般会存到微信本地缓存中,如果缓存不在了,再从后台读取)
/// </summary>
/// <returns></returns>
public ReturnResult GetAllArea()
{
ReturnResult rr = new ReturnResult() { IsError = true };
try
{
using (testEntities db = new testEntities())
{
WxAreaModel models = new WxAreaModel();
var obj = CacheHelper.GetCache("WxAreaModel");//先直接从缓存获取,如果缓存没了再重新从原始地址信息中组合整理
if (obj != null)
{
models = (WxAreaModel)obj;
}
else
{
List<T_Areas> areaList = CacheHelper.GetListFromCache("T_Areas", db.T_Areas);//读取原始地址信息
List<wxProvince> provinces = new List<wxProvince>();
Dictionary<int, List<wxCity>> cityss = new Dictionary<int, List<wxCity>>();
Dictionary<int, List<wxArea>> areass = new Dictionary<int, List<wxArea>>();
//筛选出所有省份
var provAreaList = areaList.Where(t => t.Area_Level == 1).ToList();
foreach (T_Areas prov in provAreaList)
{
//插入省份数据
provinces.Add(new wxProvince() { id = prov.Area_ID, name = prov.Area_Name });
//筛选出这个省份下的所有城市
List<wxCity> citys = new List<wxCity>();
var cityAreaList = areaList.Where(t => t.Area_Parent_ID == prov.Area_ID).ToList();
foreach (T_Areas c in cityAreaList)
{
//插入城市数据
citys.Add(new wxCity() { province = prov.Area_Name, id = c.Area_ID, name = c.Area_Name });
List<wxArea> areas = new List<wxArea>();
//筛选出这个城市下的所有区县
var areaAreaList = areaList.Where(t => t.Area_Parent_ID == c.Area_ID).ToList();
foreach (T_Areas a in areaAreaList)
{
//插入区县数据
areas.Add(new wxArea() { city = c.Area_Name, id = a.Area_ID, name = a.Area_Name });
}
areass.Add(c.Area_ID, areas);
}
cityss.Add(prov.Area_ID, citys);
}
models.provinces = provinces;
models.citys = cityss;
models.areas = areass;
CacheHelper.SetCache("WxAreaModel", models);
}
rr.Result = models;
rr.IsError = false;
}
return rr;
}
catch (Exception ex)
{
LogHelper.WriteLogError(MethodBase.GetCurrentMethod(), System_Log_Operate.用户注册, ex.Message);
rr.Msg = ex.Message;
return rr;
}
}