弄懂art-template前后端混合使用之后,使用mongodb数据库,Node.js,AJAX,art-template实现省市区三级联动

弄懂art-template前后端混合使用之后,完成的这个案例

首先,页面用服务器端渲染,拿到省份信息,渲染到页面
其次,客户端省份信息选择之后调用城市接口,获取数据,渲染到页面,注意,(1)在客户端没有选中时让城市的下拉框清空,避免省份还在提示请选择省份时,城市诓就有信息(2)省份框选中时,让县城框清空,同样,避免还未选城市呢,县城信息就出来
然后,选择了城市之后,调接口用数据渲染县城框

服务器端渲染主页面代码

//导入省份,城市,area数据模块
const {Province} = require('../model/addrSelectPro');
const {City} = require('../model/addrSelectCity');
const {Area} = require('../model/addrSelectArea');
//// 一开始就请求省份,渲染到页面
app.get('/addrSelectPro',async (req,res)=>{
    // 获取所有省份的信息
    var provinceArry = await Province.find();
    //渲染index.art模板
    res.render('index',{provinceArry});
});
//请求城市信息
app.get('/addrSelectCity/:province',async (req,res)=>{
    // 获取请求参数省份名称
    var {province} = req.params;
    // 查询省份具体的信息
    var  proInfo = await Province.findOne({province:province});    
    // 根据省份id查城市信息
    var cityArry = await City.find({province:proInfo._id});
    //将城市数据传回,注意我传的时对象
    res.send({cityArry}); 
}
// 请求县城信息
app.get('/addrSelectArea/:city', async (req,res)=>{
    // 获取参数城市名
    var {city} = req.params;
    // 查询城市对应的信息以便获取城市id
    var  cityInfo = await City.findOne({city:city});
    // 根据城市id查县城信息
    var areaArry = await Area.findOne({city:cityInfo._id});
    //将县城数据传回,注意我传的时对象
    res.send({areaArry}); 
}

客户端主页面index.art

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>  
</head>
<body>
    <select name="province" id="provinceBox" class="form-control">
        <option>请选择省份</option>
        {{each provinceArry}}
            <option value="{{$value.province}}">{{$value.province}}</option>
        {{/each}}
    </select>
    <select name="city" id="cityBox">
        <option>请选择城市</option>
    </select>
    <select name="area" id="areaBox" class="form-control">
        <option >请选择县城</option>
    </select>
    <script src="/js/template-web.js"></script>
    <script src="/js/jquery.js"></script>
     // 下拉显示城市地址模块
    <script id="cityTpl" type="text/html">
        <option>请选择城市</option>
        <% for(var i=0;i< cityArry.length;i++){%>
            <option value="<%=cityArry[i].city%>"><%=cityArry[i].city%></option>
        <%}%>
    </script>
    // 下拉显示县城地址模块
    <script id="areaTpl" type="text/html">
        <option>请选择城市</option>
        <% for(var i=0;i< areas.length;i++){%>
            <option value="<%=areas[i]%>"><%=areas[i]%></option>
        <%}%>
    </script>
    //导入页面的js代码
    <script src="/js/test.js"></script>
</body>
</html>

页面的js代码test.js

// 省份盒子点击时,清空城市盒子(省份盒子未发生change事件的处理)
$('#provinceBox').on('click',function(){
    var province = $('#provinceBox').val();
    // 清空城市下拉框,也就是让城市的渲染数据为空数据就行
    var html = template('cityTpl', {
        cityArry: []
    });
    $('#cityBox').html(html);
});
// 城市box的事件
$('#provinceBox').on('change',function(){
    // 获取当前选择的省份
    var province = $('#provinceBox').val();
    console.log(province);
    // 清空县城下拉框,也就是让县城的渲染数据为空数据就行
    var html = template('areaTpl', {
        areas: []
    });
    $('#areaBox').html(html);
    $.ajax({
        type:'get',
        url:'/home/addrSelectCity/'+province,
        success:function(response){
            var {cityArry} = response;
            var html = template('cityTpl',{
                cityArry
            })
            $('#cityBox').html('');
            $('#cityBox').html(html);
        }
    })
})
// 县城box的事件
$('#cityBox').on('change',function(){
    // 获取当前选择的省份
    var city = $('#cityBox').val();
    $.ajax({
        type:'get',
        url:'/home/addrSelectArea/'+city,
        success:function(response){
            var {areaArry} = response;
            console.log(areaArry.areas);   
            var html = template('areaTpl',{
                areas:areaArry.areas
            })
            $('#areaBox').html('');
            $('#areaBox').html(html);
        }
    })
})

省份数据模块addrSelectPro.js

const mongoose  = require('mongoose');
// 创建规则
const addrSelectProSchema = new mongoose.Schema({
    province:{
        type:String,
        required:true
    }
})
// 创建省份集合
const Province = mongoose.model('Province',addrSelectProSchema);
//导出模块
module.exports = {
    Province
}

城市数据模块addrSelectCity.js

const mongoose  = require('mongoose');
// 创建规则
const addrSelectCitySchema = new mongoose.Schema({
    province:{
        type:mongoose.Schema.Types.ObjectId,
        ref:'Province',
        required:true
    },
    city:{
        type:String,
        required:true
    }
})
//创建城市集合
const  City = mongoose.model('City',addrSelectCitySchema);
//导出模块
module.exports = {
    City
}

县城数据模块addrSelectArea.js

const mongoose  = require('mongoose');
// 创建规则
const addrSelectAreaSchema = new mongoose.Schema({
    city:{
        type:mongoose.Schema.Types.ObjectId,
        ref:'City',
        required:true
    },
    areas:{
        type:[],
        required:true
    }
})
//创建县城集合
const  Area =  mongoose.model('Area',addrSelectAreaSchema);
//导出模块
module.exports = {
    Area
}

今天就干了这一件事,虽然有点少,但是学会了,疑惑少了,很开心。

省市区市联动注意事项(踩坑总结)

  1. 不能再点击某个框时去渲染这个框,这样的话你动态生成的option它是没办法选中的,而且它还不太灵光,哈哈,虽然是创建了,但是前一两次的时候他给你显示出来的就只有一个option的高度,其他的option需要鼠标滑动才能显示,非常不好。解决方法:在上一个框选择之后就渲染好这个框,这样就不会有问题了。
  2. 在省份没有选择时,要清空城市框的内容。为啥呢?因为如果你第一次选择了省份了城市也选择了,那么此时你再反过头来把省份设个请选择省份,这个时候城市框可是还能选择的,这可不符合逻辑啊。
  3. 在省份选中时,要清空县城框的内容。为啥呢?因为如果 之前你把省市区三个都选择了,此时你再翻回来选择省份了,此时县城的信息都还是存在的呢,你说此时都不知道呢就有县城的信息了,这样是不是不合逻辑。不会有人要问这时候为啥不清空城市框呢吧,还是再多解释一句,省份框选中之后它就是要渲染城市框的呀,城市框的数据都是这么来的,没选中之前咋们这个此时框可是没有数据的哦,哈哈,有点自娱自乐了。
  4. 我个人在刚开始是在点击那个框请求那个框的数据来着,还捉摸了半天嘞,onchange和click,甚至是onfocus都试过,都是有渲染框时显示高度不正常,或者是不能选择的问题,希望大家不要再踩坑了!

结术语

今天的这篇博客我个人觉得很完整了,希望大家可以从中学习到东西,汝以我而得获,其余而喜之也!哈哈

你可能感兴趣的:(art-template,mongodb,node.js)