引言:上期我们介绍了“微天气”的API与界面代码编写,今天我们继续介绍逻辑层代码以及查询代码的编写。
本文选自《从零开始学微信小程序开发》。
由于在index.js中还没有设置初始化数据,所以在界面中看不到具体的数据,从而也导致界面的效果没达到设置的要求。
接下来就编写逻辑层代码index.js,为了检查界面设计效果,首先编写初始数据,然后再逐步深入地编写其他相关业务逻辑代码。
在index.wxml中编写了很多数据,因此需要在index.js中先把这些数据进行初始化,然后在开发工具的模拟器中就可预览结果。
打开index.js文件,删除原来的内容,重新编写以下代码:
Page({
data: {
weather:{
wendu:18,
ganmao:'昼夜温差较大,较易发生感冒,请适当增减衣服。体质较弱的朋友请注意防护。',
yesterday:{
date:'17日星期四',
type:'阴',
fx:'南风',
fl:'微风级',
low:'低温 8℃',
high:'高温 16℃'
},
forecast:[
{
date:'18日星期五',
type:'阴',
high:'高温 16℃',
low:'低温 8℃',
fengxiang:'南风',
fengli:'微风级'
},{
date:'18日星期五',
type:'阴',
high:'高温 16℃',
low:'低温 8℃',
fengxiang:'南风',
fengli:'微风级'
},{
date:'18日星期五',
type:'阴',
high:'高温 16℃',
low:'低温 8℃',
fengxiang:'南风',
fengli:'微风级'
},{
date:'18日星期五',
type:'阴',
high:'高温 16℃',
low:'低温 8℃',
fengxiang:'南风',
fengli:'微风级'
},{
date:'18日星期五',
type:'阴',
high:'高温 16℃',
low:'低温 8℃',
fengxiang:'南风',
fengli:'微风级'
}
]
},
today:'2016-11-18',
city:'北京', //城市名称
inputCity:'', //输入查询的城市名称
}
})
编写好以上初始化数据之后,保存index.js,在开发工具左侧预览区域可看到如下的界面效果。
以上代码很长,主要是由于模拟了5天的天气数据,实际上,在小程序运行时,应该在打开小程序之后就马上通过API获取天气数据,因此上面的初始化数据代码中,只需要用以下语句将weather初始化为一个空对象即可,而上面添加在weather中的属性数据都可以删除。
weather:{}
根据本案例的要求,当用户打开本案例之后,首先要获取用户当前所在城市的天气信息,这就需要获取用户当前所在城市的名称。要完成这个功能,需要经过几个转折。
首先,可以使用微信小程序的获取当前地理位置经纬度的API(就是wx. getLocation),通过该API即可获取用户所在位置的经纬度。
有了用户所在的经纬度,还需要查询该经纬度对应的城市名称。这可以使用百度地图的接口来实现,百度地图Geocoding API服务地址如下:
http://api.map.baidu.com/geocoder/v2/
调用该接口需要传递以下几个参数。
例如,在浏览器中输入以下地址:
http://api.map.baidu.com/geocoder/v2/ak=ASAT5N3tnHIa4APW0SNPeXN5&location=30.572269,104.066541&output=json&pois=0
返回的JSON格式如下所示:
{
"status": 0,
"result": {
"location": {
"lng": 104.06654099999996,
"lat": 30.572268897395259
},
"formatted_address": "四川省成都市武侯区G4201(成都绕城高速)",
"business": "",
"addressComponent": {
"country": "中国",
"country_code": 0,
"province": "四川省",
"city": "成都市",
"district": "武侯区",
"adcode": "510107",
"street": "G4201(成都绕城高速)",
"street_number": "",
"direction": "",
"distance": ""
},
"pois": [],
"poiRegions": [],
"sematic_description": "环球中心w6区西南108米",
"cityCode": 75
}
}
在以上JSON数据中,通过result.addressComponent.city可获取传入经纬度对应的城市名称。因此,在本案例中可通过这种方式获取用户当前所在城市的名称。
根据以上分析,在index.js的onLoad事件处理函数中编写如下所示代码:
var util = require('../../utils/util.js');
Page({
data: {
……
},
onLoad: function (options) {
this.setData({
today:util.formatTime(new Date()).split(' ')[0] //更新当前日期
});
var self = this;
wx.getLocation({
type: 'wgs84',
success: function (res) {
wx.request({
url:'http://api.map.baidu.com/geocoder/v2/' +
'?ak=ASAT5N3tnHIa4APW0SNPeXN5&location='+
res.latitude+',' + res.longitude + '&output=json&pois=0',
data: {},
header: {
'Content-Type': 'application/json'
},
success: function (res) {
var city = res.data.result.addressComponent.city.replace('市','');//城市名称
self.searchWeather(city); //查询指定城市的天气信息
}
})
}
})
},
})
以上代码中,第1行使用require导入工具方法,用来格式化日期。
获取了城市名称,接下来就可使用以下接口获取指定城市名称的天气预报信息:
http://wthrcdn.etouch.cn/weather_mini?city=城市名称
在上面的接口中,城市名称中不包含“市”这个字,如“成都市”只需要传入“成都”。
在本节前面介绍该接口时,只查看了接口执行成功后返回的JSON数据,如果传入的城市名称有误,则返回如下所示JSON数据:
{
"desc": "invilad-citykey",
"status": 1002
}
在程序中可通过status判断数据查询是否成功。
由于根据城市名称查询天气预报信息的代码需要重复调用,因此,单独编写成一个函数,方便在查询时调用。
//根据城市名称查询天气预报信息
searchWeather:function(cityName){
var self = this;
wx.request({
//天气预报查询接口
url: 'http://wthrcdn.etouch.cn/weather_mini?city='+cityName,
data: {},
header: {
'Content-Type': 'application/json'
},
success: function (res) {
if(res.data.status == 1002) //无此城市
{
//显示错误信息
wx.showModal({
title: '提示',
content: '输入的城市名称有误,请重新输入!',
showCancel:false,
success: function(res) {
self.setData({inputCity:''});
}
})
}else{
var weather = res.data.data; //获取天气数据
for(var i=0;ivar d = weather.forecast[i].date;
//处理日期信息,添加空格
weather.forecast[i].date = ' ' + d.replace('星期',' 星期');
}
self.setData({
city:cityName, //更新显示城市名称
weather:weather, //更新天气信息
inputCity:'' //清空查询输入框
})
}
}
})
}
在上面代码中,获取的date中保存的是“19日星期六”这种格式的字符串,为了使日期和星期分别显示在两行中,这里使用了一种小技巧,就是在日期字符串中添加了2个全角状态的空格,这样在显示这个字符串时自动断行。
编写好以上这些代码之后,保存,在开发工具左侧可看到已经获取当前的天气数据,而不是前面初始化的数据了。
这样,本案例的主要代码就算编写完成了。不过,还只能显示用户当前所在地的天气信息,如果要查看其他城市的天气,还需要继续编写相应的查询代码。
查询代码的编写很简单,只需要获取用户输入的城市名称,然后传入searchWeather函数即可。具体的代码如下:
//输入事件
inputing:function(e){
this.setData({inputCity:e.detail.value});
},
//搜索按钮
bindSearch:function(){
this.searchWeather(this.data.inputCity);
}
保存以上代码之后,在开发工具左侧模拟器中输入查询的城市名称,如输入“三亚”,单击“查询”按钮,界面中即可显示“三亚”的天气信息。
如果在下方输入框输入一个不存在的城市名称,将显示下面的提示信息。