1. 程式人生 > >angularjs+bootstrap後臺管理樣例

angularjs+bootstrap後臺管理樣例



angularjs+bootstrap可以做出很漂亮的管理系統出來,https://wrapbootstrap.com/可以付費購買,下文會提供一個免費的,要講解如何從0到1把ng前端結構搭出來是很漫長的教程,本文僅僅介紹一下這個免費後臺模版的結構,然後重點講解如何改寫這個結構。 
開始閱讀之前,假設讀者已經ng入門並且對於ui.router,bootstrap有一定了解。

1) 後臺結構 
這裡寫圖片描述

其中我們需要關注的如下:

index.html: 入口 
js: 存放所有業務邏輯程式碼 
js/app.js:定義ng需要載入的模組 
js/main.js:定義ng的全域性配置資訊 
js/config.router.js:ng的路由器 
tpl:存放所有頁面模版 
tpl/blocks:頁面框架(頭、尾、側邊欄…) 
vendor:存放所有第三方模組

2) 改寫結構,接管路由

結構簡圖如下 
這裡寫圖片描述 
這裡接管的原則是儘量不改動原始結構,首先在根目錄建立我們自己的目錄結構.

> mkdir admin
> mkdir admin\blocks
> copy js\main.js admin\
  • 1
  • 2
  • 3

編寫頁面框架模版,我們也可以直接從tpl目錄複製過來再做修改。簡單起見,我們在模版裡面直接使用了中文,這樣會導致頁面亂碼,解決方法:html檔案用utf-8編碼格式儲存。

<!--admin/blocks/aside.html-->
<div class="aside-wrap">
  <div class="navi-wrap">
    <!-- nav -->
    <nav ui-nav class="navi" ng-include="'admin/blocks/nav.html'"></nav>
    <!-- nav -->
  </div>
</div>
<!--admin/blocks/header.html-->
      <!-- navbar header -->
      <div class="navbar-header {{app.settings.navbarHeaderColor}}">
        <button class="pull-right visible-xs dk" ui-toggle-class="show" data-target=".navbar-collapse">
          <i class="glyphicon glyphicon-cog"></i>
        </button>
        <button class="pull-right visible-xs" ui-toggle-class="off-screen" data-target=".app-aside" ui-scroll="app">
          <i class="glyphicon glyphicon-align-justify"></i>
        </button>
        <!-- brand -->
        <a href="#/" class="navbar-brand text-lt">
          <i class="fa fa-btc"></i>
          <img src="img/logo.png" alt="." class="hide">
          <span class="hidden-folded m-l-xs">{{app.name}}</span>
        </a>
        <!-- / brand -->
      </div>
      <!-- / navbar header -->

      <!-- navbar collapse -->
      <div class="collapse pos-rlt navbar-collapse box-shadow {{app.settings.navbarCollapseColor}}">
        <!-- buttons -->
        <div class="nav navbar-nav hidden-xs">
          <a href class="btn no-shadow navbar-btn" ng-click="app.settings.asideFolded = !app.settings.asideFolded">
            <i class="fa {{app.settings.asideFolded ? 'fa-indent' : 'fa-dedent'}} fa-fw"></i>
          </a>
        </div>
        <!-- / buttons -->

        <!-- nabar right -->
        <ul class="nav navbar-nav navbar-right">
          <li class="hidden-xs">
            <a ui-fullscreen></a>
          </li>
          <li class="dropdown" dropdown>
            <a href class="dropdown-toggle clear" dropdown-toggle>
              <span class="thumb-sm avatar pull-right m-t-n-sm m-b-n-sm m-l-sm">
                <img src="img/a0.jpg" alt="...">
                <i class="on md b-white bottom"></i>
              </span>
              <span class="hidden-sm hidden-md"></span> <b class="caret"></b>
            </a>
            <!-- dropdown -->
            <ul class="dropdown-menu animated fadeInRight w">
              <li>
                <a href="#">Logout</a>
              </li>
            </ul>
            <!-- / dropdown -->
          </li>
        </ul>
        <!-- / navbar right -->

      </div>
      <!-- / navbar collapse -->
<!--admin/blocks/nav.html-->
<!-- list -->
<ul class="nav">
  <li class="hidden-folded padder m-t m-b-sm text-muted text-xs">
    <span translate="導航">導航</span>
  </li>  
</ul>
<!-- / list -->
<!--admin/app.html-->
  <!-- navbar -->
  <div data-ng-include=" 'admin/blocks/header.html' " class="app-header navbar">
  </div>
  <!-- / navbar -->

  <!-- menu -->
  <div data-ng-include=" 'admin/blocks/aside.html' " class="app-aside hidden-xs {{app.settings.asideColor}}">
  </div>
  <!-- / menu -->

  <!-- content -->
  <div class="app-content">
    <div ui-butterbar></div>
    <a href class="off-screen-toggle hide" ui-toggle-class="off-screen" data-target=".app-aside" ></a>
    <div ncy-breadcrumb></div>
    <div class="app-content-body fade-in-up" ui-view></div>
  </div>
  <!-- /content -->

  <!-- footer -->
  <div class="app-footer wrapper b-t bg-light">
    <span class="pull-right">{{app.version}} <a href ui-scroll="app" class="m-l-sm text-muted"><i class="fa fa-long-arrow-up"></i></a></span>
    &copy; 2016 Copyright.
  </div>
  <!-- / footer -->

  <div data-ng-include=" 'tpl/blocks/settings.html' " class="settings panel panel-default">
  </div>

給我們的首頁建立一個空白模版admin/dashboard.html

<!--admin/dashboard.html-->

寫我們新的路由

// admin/router.js
'use strict';

app
  .run(
      function ($rootScope,   $state,   $stateParams) {
          $rootScope.$state = $state;
          $rootScope.$stateParams = $stateParams;        
      }
  )
.config(
      function ($stateProvider,   $urlRouterProvider) {
          $urlRouterProvider
              .otherwise('/app/dashboard');
          $stateProvider
              .state('app', {
                  abstract: true,
                  url: '/app',
                  templateUrl: 'admin/app.html',
              })
              .state('app.dashboard', {
                  url: '/dashboard',
                  templateUrl: 'admin/dashboard.html',
              })
      }
  );

修改入口,註釋或刪除掉對原config.router.js、main.js的引用,換成我們的控制接管

<!--index.html-->
...
  <!--<script src="js/config.router.js"></script>-->
  <!--<script src="js/main.js"></script>-->
  <script src="admin/router.js"></script>
  <script src="admin/main.js"></script>
...

這裡寫圖片描述
到此我們就得到了一套可自由擴充套件的前端框架

3) 接下來我們基於BasicAuth加入系統的使用者驗證功能。

這裡寫圖片描述 
這裡我們採用按功能模組來建立子目錄,區別於原模版框架(原框架是按檔案型別區分子目錄,例如指令碼放在js/裡面,模版放在tpl裡面)。

首先啟動Restful伺服器,然後我們為伺服器配置一個全域性變數,程式碼裡面的host需要修改成伺服器真實地址

// admin/main.js
...
      $scope.app = {
        host: "http://172.17.9.92:8000",
        name: 'Angulr',
...

建立認證功能模組目錄auth

> mkdir admin\auth\

編寫controller(控制器)

// admin/auth/ctrl.js
app.controller('LoadingController',function($scope,$resource,$state){
    var $com = $resource($scope.app.host + "/auth/info/?");
    $com.get(function(){
        $state.go('app.dashboard');
    },function(){
        $state.go('auth.login');
    })  
});
app.controller('LoginController',function($scope,$state,$http,$resource,Base64){
    $scope.login = function(){
        $scope.authError = ""
        var authdata = Base64.encode($scope.user.username + ':' + $scope.user.password);
        $http.defaults.headers.common['Authorization'] = 'Basic ' + authdata;
        var $com = $resource($scope.app.host + "/auth/info/?");
        $com.get(function(){
            $state.go('app.dashboard');
        },function(){
            $scope.authError = "伺服器登入錯誤"
        })
    }
});
app.factory('Base64',function(){
    var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    return {
        encode: function (input) {
            var output = "";
            var chr1, chr2, chr3 = "";
            var enc1, enc2, enc3, enc4 = "";
            var i = 0;

            do {
                chr1 = input.charCodeAt(i++);
                chr2 = input.charCodeAt(i++);
                chr3 = input.charCodeAt(i++);

                enc1 = chr1 >> 2;
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
                enc4 = chr3 & 63;

                if (isNaN(chr2)) {
                    enc3 = enc4 = 64;
                } else if (isNaN(chr3)) {
                    enc4 = 64;
                }

                output = output +
                    keyStr.charAt(enc1) +
                    keyStr.charAt(enc2) +
                    keyStr.charAt(enc3) +
                    keyStr.charAt(enc4);
                chr1 = chr2 = chr3 = "";
                enc1 = enc2 = enc3 = enc4 = "";
            } while (i < input.length);

            return output;
        },

        decode: function (input) {
            var output = "";
            var chr1, chr2, chr3 = "";
            var enc1, enc2, enc3, enc4 = "";
            var i = 0;

            // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
            var base64test = /[^A-Za-z0-9\+\/\=]/g;
            if (base64test.exec(input)) {
                window.alert("There were invalid base64 characters in the input text.\n" +
                    "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
                    "Expect errors in decoding.");
            }
            input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

            do {
                enc1 = keyStr.indexOf(input.charAt(i++));
                enc2 = keyStr.indexOf(input.charAt(i++));
                enc3 = keyStr.indexOf(input.charAt(i++));
                enc4 = keyStr.indexOf(input.charAt(i++));

                chr1 = (enc1 << 2) | (enc2 >> 4);
                chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
                chr3 = ((enc3 & 3) << 6) | enc4;

                output = output + String.fromCharCode(chr1);

                if (enc3 != 64) {
                    output = output + String.fromCha