从数据库动态加载菜单栏

从数据库动态加载菜单栏

最近组内有个技术学习项目—用Python写一个Web站点,我领取的任务是将站点菜单可配置,从数据库中读取数据,然后动态构建。
基本的思路是这样:把需要显示的菜单数据存储在数据库,页面加载的时候,JS从后台读取数据,在前端构建Dome并正确显示。

第一步:设计数据库

1.1.数据库字段设计

ID:菜单节点记录唯一识别字段,设为主键
Name:菜单节点的名称
ShowName:菜单节点在前端显示的名称
IshasSon:是否有子节点,为了处理菜单层级不确定的问题
ParentId:父节点的ID
NodeUrl:菜单节点对应的跳转URL
IsNewBlank:是否在新窗口打开,内/外站点打开的方式不同
CreatTime:菜单记录的创建时间

menu数据库设计图:

1.2 数据库读取:

创建py文件dbMenu,导入数据库连接方法(具体方法可参见我的另一篇博客 Python连接MySql数据库),获取数据库连接句柄后查询数据库,获取所有的数据库记录。代码如下:
from config import Config
from app.db.dbBase import DBConnect
import pymysql.cursors


class DBMenu:
    @staticmethod
    def get_nodes():
        conn = DBConnect().db_connect(Config().DATABASE_MAIN)
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        cursor.execute("select * from menu")
        menus = cursor.fetchall()
        cursor.close()
        conn.close()
        return menus

    @staticmethod
    def get_sonnodes(node_id):
        conn = DBConnect().db_connect(Config().DATABASE_MAIN)
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        cursor.execute("select * from menu where `parent_id` = %s", node_id)
        sonmenus = cursor.fetchall()
        cursor.close()
        conn.close()
        return sonmenus
get_nodes()是一个获取所有菜单节点的方法,用来构建根菜单;get_sonnodes()是一个根据当前节点ID获取其子节点菜单的方法,用来构建子菜单

第二步:读取数据库菜单记录,动态构建菜单

2.1 Controler 层实现获取数据方法:

创建py文件cMenu,实现获取数据方法,封装数据源,代码如下:
from app.db.dbMenu import DBMenu


class CMenu:
    @staticmethod
    def get_menu():
        menus = DBMenu.get_nodes()
        return menus

    @staticmethod
    def get_sonmenu(node_id):
        sonmenu = DBMenu.get_sonnodes(node_id)
        return sonmenu

2.2 View层把数据传递给Html模版文件:

创建py文件menu,把封装好的数据传递给模版文件,代码如下:
# This Python file uses the following encoding: utf-8
from flask import request

from app.controler.cMenu import CMenu
from flask import Blueprint
from flask import jsonify


commonBp = Blueprint('common', __name__, url_prefix='/common')


@commonBp.route('/getSonMenu', methods=['GET'])
def get_sonmenu():
    parentid = request.args.get('parentId')
    node = CMenu.get_sonmenu(int(parentid))
    return jsonify(node)


@commonBp.route('/getmenu')
def base():
    menus_node = CMenu.get_menu()
    size = len(menus_node)
    return jsonify(menus_node=menus_node, size=size)

2.3 Html模版文件前端构建页面内容:

创建base.html文件,构建前端Html,代码如下:
<nav id="Hui-nav" class="nav navbar-nav">
                <ul class="cl" id="ulmenu">
                </ul>
</nav>

2.4 JS动态加载菜单:

创建my.js,JS脚本动态加载菜单,代码如下:
$(document).ready(function () {

    function getRootmenu() {
        $.ajax({
            type: "get",
            dataType: "json",
            url: "/common/getmenu",
            success: function (data) {
                var m = "";
                if (data.size > 0) {
                    for (j = 0; j < data.size; j++) {
                        if (data.menus_node[j].parent_id == -1) {
                            if (data.menus_node[j].ishas_son == 1) {
                                m = m + "<li roletype='2' id='" + data.menus_node[j].node_id + "' class='dropDown dropDown_hover'>" +
                                    "<a class='dropDown_A' href='" + data.menus_node[j].node_url + "'>" + data.menus_node[j].node_showname + "<i class='Hui-iconfont' >" + '' + "</i></a></li>";

                            }
                            else {
                                m = m + "<li roletype='2' id='" + data.menus_node[j].node_id + "' class='dropDown dropDown_hover'>" +
                                    "<a class='dropDown_A' href='" + data.menus_node[j].node_url + "'>" + data.menus_node[j].node_showname + "</a></li>";

                            }
                        }
                    }
                }
                $('#ulmenu').html(m);
                $("#ulmenu li").bind('mouseover', function (e) {
                    getSonMenu(this, e)
                });
            }
        });
    }
    getRootmenu();


    function getSonMenu(event) {
        var parentId = $(event).attr("id");
        var roletype = $(event).attr("roletype");
        if (roletype == "2")
            $(event).addClass("hover open");
        if (roletype == "1")
            $(event).addClass("open");
        if ($(event).find("li").length > 0 || roletype == "0") return;
        $.ajax({
            type: "get",
            dataType: "json",
            url: "/common/getSonMenu?parentId=" + parentId,
            success: function (result) {
                var parentId = $(event).attr("id");
                $('#' + parentId).html($('#' + parentId + ' >a'))
                // $('#'+parentId).html("");
                var a = "<ul class='dropDown-menu menu radius box-shadow'>";
                var b = "</ul>";
                var c = "";
                $.each(result, function (i) {
                    if(result[i].isnewblank == 1 && result[i].ishas_son == 1)
                        {
                            c = c + "<li roletype='" + result[i].ishas_son + "' id=" + result[i].node_id + "><a href='" + result[i].node_url + "' target='_blank'>" + result[i].node_showname + "<i class='arrow Hui-iconfont'></i></a></li>";
                        }
                    if(result[i].isnewblank == 1 && result[i].ishas_son == 0){
                            c = c + "<li roletype='" + result[i].ishas_son + "' id=" + result[i].node_id + "><a href='" + result[i].node_url + "' target='_blank'>" + result[i].node_showname + "</a></li>";
                    }
                    if(result[i].isnewblank == 0 && result[i].ishas_son == 1){
                            c = c + "<li roletype='" + result[i].ishas_son + "' id=" + result[i].node_id + "><a href='" + result[i].node_url + "'>" + result[i].node_showname + "<i class='arrow Hui-iconfont'></i></a></li>";
                    }
                    if(result[i].isnewblank == 0 && result[i].ishas_son == 0){
                            c = c + "<li roletype='" + result[i].ishas_son + "' id=" + result[i].node_id + "><a href='" + result[i].node_url + "'>" + result[i].node_showname + "</a></li>";
                    }
                });
                $('#' + parentId).append(a + c + b);
                $("#ulmenu li").unbind('mouseover');
                $("#ulmenu li").bind('mouseover', function (e) {
                    getSonMenu(this, e)
                });
            }, error: function (result) {
                alert(result.responseText);
            }
        });
    }

});
记得要在Html文件中引用一下Js
<script type="text/javascript" src="/static/js/my.js"></script>

第三步:运行项目,打开浏览器看下效果:





Done!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值