AngularJS體驗式編程系列文章,將介紹如何用angularjs構建一個強大的web前端系統。angularjs是由Google團隊開發的一款非常優秀web前端架構。在當前如此多的web架構下,angularjs能脫穎而出,從架構設計上就高人一等,雙向資料繫結,依賴注入,指令,MVC,模板。Angular.js創新地把後台技術融入前端開發,掃去jQuery一度的光芒。用angularjs就像寫後台代碼,更規範,更結構化,更可控。
關於作者 張丹(Conan), 程式員Java,R,PHP,Javascript weibo:@Conan_Z blog: http://blog.fens.me email: bsspirit@gmail.com
轉載請註明出處:
http://blog.fens.me/bootstrap-multilevel-navbar/
前言
在上一篇文章中Angular結合Bootstrap3的導覽功能表,我們看到直接用Bootstrap3的預設導覽功能表只支援到二級的菜單,如果想做成多級導覽功能表,那又要自己動手了。
本文將介紹如何?多限級導覽功能表。
目錄 靜態多級菜單實現 動態多級菜單實現 1. 靜態多級菜單實現
要實現多級菜單,我們要分兩步走,第一步就是把靜態菜單的功能實現,通過純靜態HTML程式碼完成。第二步,通過Angluarjs進行動態實現,最後把資料和程式分離,通過Ajax載入多級菜單資料。
我們先從靜態多級菜單開始動手,一個六級導覽功能表是什麼樣子呢。
如上圖所示,我們定義一些功能需求。 1級菜單是導航條上的文字。 當1級菜單導航事件被觸發,顯示2級菜單導航,在1級菜單的正下方顯示。 當2級菜單導航事件被觸發,顯示3級菜單導航,在2級菜單的右方顯示。 當3級菜單導航事件被觸發,顯示4級菜單導航,在3級菜單的右方顯示。 以此類推,不考慮下級菜單顯示出界問題。
繼續上文中的項目環境,增加一個新HTML檔案: page3.html
~ vi D:\workspace\javascript\angular-navbar\page3.html<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8"> <title>多級導覽功能表</title> <meta name="description" content="多級導覽功能表"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="fragment" content="!" /> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/main.css"></head><body ng-app="page2"><div class="container"> <div class="row" ng-controller="NavbarCtrl"> <nav class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <a class="navbar-brand" href="#">多級菜單導航</a> </div> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Multi Level <b class="caret"></b></a> <ul class="dropdown-menu menu-top"> <li><a href="#">Level 1</a></li> <li class="dropdown-submenu"> <a tabindex="-1" href="#">More options</a> <ul class="dropdown-menu"> <li><a tabindex="-1" href="#">Level 2</a> </li> <li class="dropdown-submenu"> <a href="#">More..</a> <ul class="dropdown-menu"> <li><a href="#">Level 3</a> </li> <li><a href="#">Level 3</a> </li> <li class="dropdown-submenu"> <a href="#">More..</a> <ul class="dropdown-menu"> <li><a href="#">Level 4</a> </li> <li><a href="#">Level 4</a> </li> <li class="dropdown-submenu"> <a href="#">More..</a> <ul class="dropdown-menu"> <li><a href="#">Level 5</a> </li> <li><a href="#">Level 5</a> </li> </ul> </li> </ul> </li> </ul> </li> <li><a href="#">Level 2</a> </li> <li><a href="#">Level 2</a> </li> </ul> </li> <li><a href="#">Level 1</a></li> </ul> </li> </ul> </div> </nav> </div></div><script src="/bower_components/jquery/dist/jquery.min.js"></script><script src="/bower_components/angular/angular.min.js"></script><script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script src="/bower_components/angular-route/angular-route.min.js"></script><script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script><script src="/js/app.js"></script></body></html>
建立一個css檔案:main.css
~ vi D:\workspace\javascript\angular-navbar\css\main.css.dropdown:hover .menu-top { display: block;}.dropdown-submenu{ position:relative;}.dropdown-submenu > .dropdown-menu{ top:0; left:100%; margin-top:-6px; margin-left:-1px; -webkit-border-radius:0 6px 6px 6px; -moz-border-radius:0 6px 6px 6px; border-radius:0 6px 6px 6px;}.dropdown-submenu:hover > .dropdown-menu{ display:block;}.dropdown-submenu > a:after{ display:block; content:" "; float:right; width:0; height:0; border-color:transparent; border-style:solid; border-width:5px 0 5px 5px; border-left-color:#cccccc; margin-top:5px; margin-right:-10px;}.dropdown-submenu:hover > a:after{ border-left-color:#ffffff;}.dropdown-submenu .pull-left{ float:none;}.dropdown-submenu.pull-left > .dropdown-menu{ left:-100%; margin-left:10px; -webkit-border-radius:6px 0 6px 6px; -moz-border-radius:6px 0 6px 6px; border-radius:6px 0 6px 6px;}
重新整理一下網頁,我們能就看到上面的截圖的效果,代碼參考:http://firdaus.grandexa.com/2013/09/twitter-bootstrap-3-multilevel-dropdown-menu/
通過HTML和CSS就實現了多級菜單的靜態展示效果,如果導覽功能表不是經常變化,那麼用靜態方式,把代碼寫死就可以了。但有一些情境,菜單是需要動態產生,比如通過許可權控制訪問連結,每個使用者的許可權不一樣,那麼能看到的菜單選項也就不一樣,這個時候就需要做成動態,用程式去控制功能表的載入和展示。 2. 動態多級菜單實現
有了靜態多級導覽功能表的HTML代碼結構,改寫成動態,其實也不太複雜。
我們需要做2件事: 把導覽功能表的資料結構化儲存,比如 存放到檔案 nav.json。 用Angularjs的API載入nav.json資料,進行展示。
我們先定義一下導覽功能表的資料格式,以JSON格式定義,每個功能表項目都有3個屬性欄位 label: 導覽功能表項顯示的名字。 link: 導覽功能表項的跳轉連結,可以不定義。 children: 導覽功能表項的子功能表,迴圈Object Storage Service。
{ "label": "levelA", "link": "#", "children": [ { "label": "levelB", "link": "#", "children": [] } ]}
下面我們用真實的資料定義導覽功能表,以我的金融系統為例。
建立JSON資料檔案:nav.json。
~ vi D:\workspace\javascript\angular-navbar\js\nav.json[ { "label": "債券", "children": [ { "label": "可轉債", "children": [ {"label": "可轉債溢價率分析","link":"#"}, {"label": "可轉債NS定價","link":"#"}, {"label": "可轉債歸因分析","link":"#"}, {"label": "可轉債套利即時監控","link":"#"} ] }, { "label": "信用債", "children": [ {"label": "證券交易所債券監控","link":"#"} ] }, { "label": "利率債","link":"#", "children": [] }, { "label": "國債期貨", "children": [ {"label": "國債期貨表現分析","link":"#"}, {"label": "國債期貨即時套利監控","link":"#"}, {"label": "IRR曆史時間序列查詢","link":"#"}, {"label": "IRR即時監控","link":"#"} ] } ] }, { "label": "股票", "children": [ { "label": "基本面分析", "children": [ {"label": "上市公司基本面資料查看","link":"#"} ] }, { "label": "量化選股策略", "children": [] } ] }, { "label": "宏觀", "children": [ { "label": "宏觀資料", "children": [ {"label": "宏觀資料概覽","link":"#"} ] }, { "label": "宏觀經濟預測", "children": [] }, { "label": "宏觀經濟和大類資產表現", "children": [] } ] }]
我們看到這個導覽功能表的資料,有3級,“債券–>可轉債–>可轉債歸因分析”,那麼接下我們就直接實現對三級菜單的編程。建立HTML檔案page4.html。
~ vi D:\workspace\javascript\angular-navbar\page4.html<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8"> <title>多級動態導覽功能表</title> <meta name="description" content="多級動態導覽功能表"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="fragment" content="!" /> <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="/css/main.css"></head><body ng-app="page4"><div class="container"> <div class="row" ng-controller="NavbarCtrl"> <nav class="navbar navbar-default" role="navigation"> <div class="navbar-header"> <a class="navbar-brand" href="/">量化投資平台</a> </div> <div class="collapse navbar-collapse navbar-ex1-collapse"> <ul class="nav navbar-nav"> <li ng-repeat="a1 in navbar" class="dropdown"> <a href="?{{ a1.label }}" class="dropdown-toggle" data-toggle="dropdown">{{ a1.label }} <b class="caret"></b></a> <ul class="dropdown-menu menu-top"> <li ng-repeat="a2 in a1.children" class="dropdown-submenu"> <a tabindex="-1" href="?{{ a2.label }}">{{ a2.label }}</a> <ul ng-show="a2.children.length>0" class="dropdown-menu"> <li ng-repeat="a3 in a2.children"> <a href="?{{ a3.label }}" ng-click="go(a3.link)">{{ a3.label }}</a> </li> </ul> </li> </ul> </li> </ul> </div> </nav> </div></div><script src="/bower_components/jquery/dist/jquery.min.js"></script><script src="/bower_components/angular/angular.min.js"></script><script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script src="/bower_components/angular-route/angular-route.min.js"></script><script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script><script src="/js/app.js"></script></body></html>
在Angularjs的控制器檔案app.js檔案中,增加page4的定義。
var page4 = angular.module('page4', ['ui.bootstrap', 'ngRoute']);page4.config(['$routeProvider', '$locationProvider', '$sceProvider', function ($routeProvider, $locationProvider, $sceProvider) { $routeProvider .when('/', {controller: 'DemoCtrl'}) .otherwise({redirectTo: '/'}); $locationProvider.html5Mode(true);}]);page4.controller('NavbarCtrl', function ($scope,$http,$location) { $http.get("/js/nav.json").success(function(json){ $scope.navbar = json; });});page4.controller('DemoCtrl', function () { // nothing});
查看一下顯示效果,與上面的截圖類似。
文章到這裡就結束了,已經實現了我的功能需求。但這個話題還有很多可以最佳化的地方,比如實現無限級的導覽功能表,菜單的展示樣式替換,展示區間的控制,滑鼠動作事件,封裝成Angularjs的外掛程式開源項目等。有興趣的同學,可以我的程式的基礎上繼續努力,做出優秀的開源項目來。
代碼已上傳到github:https://github.com/bsspirit/angular-navbar,同學可以根據需要自行下載,也可以直接通過命令下載代碼。
git clone https://github.com/bsspirit/angular-navbar.gitcd angular-navbarbower installanywhere
轉載請註明出處:
http://blog.fens.me/bootstrap-multilevel-navbar/