簡介
Bootstrap是Twitter推出的一個用於前端開發的開源工具包,它由Twitter的設計師Mark Otto和Jacob Thornton合作開,是一個CSS/HTML框架。
AngularJS是Google 開源出來的一套 js 工具,為了克服HTML在構建應用上的不足而設計的,試圖成為WEB應用中的一種端對端的解決方案,通過為開發者呈現一個更高層次的抽象來簡化應用的開發,后面簡稱"ng"。
Seajs是一款優秀的模塊開發插件,可以實現按需加載。
Bootstrap有自己的一套js庫,但是為了防止與AngularJS產生兼容性的問題,我們不選擇使用,只是使用它的css而已,因此這里我還要引入另外一個基於Bootstrap與AngularJS的UI組件--UI-Bootstrap,雖然該庫提供的控件並不多,但是基本夠用,而且可以參考它的代碼來自己實現復雜的控件(后面的文章再講)。
背景
當前Web前端開發中,我們已經可以很熟練的使用jQuery在對數據交互的時候來操作關聯Dom的一些內容、樣式等狀態上的變化,然而很多的這些變化是代碼重復的,雖然它並不復雜,但是有些確實需要大量的代碼來進行操作;雖然jQuery為我們提供了大量的操作方式來減少復雜性,但是每次我們都要從頁面中找尋一些相關的元素改變狀態是重復且難以避免的,那么怎么樣才能從這種重復的操作中解脫呢?
MVVM便可以讓我們從這種重復的操作中解脫出來,簡單的說MVVM就是我們將需要操作的元素與ViewModel進行綁定,當我們對ViewModel進行操作導致其狀態發生變化的時候,與之相關的元素會自動發生變化。
由於我也使用jQuery開發了較長的時間,雖然前幾年就已經有前端MVVM框架出現,卻沒有能讓我覺得比原始方式更簡單的,但是技術總是在發展的並趨向成熟,現在就可以將以上提到的3種框架進行結合,大大簡化Web前端的開發(雖然需要一段時間的學習和適應),接下來就讓我們一起來使用這3中框架進行開發吧(這里我不會對各個庫有詳細的介紹,有些地方仍然需要自己去學習)。
實現
首先我們從登錄功能開始着手,登錄界面比較簡單,html代碼如下:
1 <body class="container" ng-app="login"> 2 <form name="frmLogin" class="col-sm-offset-4 col-sm-4" role="form" ng-controller="HomeLoginController"> 3 <input name="txtName" ng-model="name" type="text" class="form-control input-lg" placeholder="請輸入用戶名" required autofocus /> 4 <input name="txtPwd" ng-model="pwd" type="password" class="form-control input-lg" placeholder="密碼" required /> 5 <button class="btn-lg btn-primary btn-block" ng-click="submit()">登錄</button> 6 <alert ng-repeat="a in alerts" type="a.type" close="closeAlert($index)">{{a.msg}}</alert> 7 </form> 8 </body>
這里不使用ngSubmit、ngShow、ngHide是因為有一些注意點需要講解,登錄的流程是當點擊登錄按鈕的時候,如果用戶名、密碼未填寫的情況下,會在登錄按鈕下面增加2個Alert提醒框,js代碼如下:
angular.module('login', ['ui.bootstrap']); function HomeLoginController($scope) { $scope.alerts = []; $scope.submit = function () { if ($scope.frmLogin.txtName.$invalid) $scope.alerts.push({ type: 'danger', msg: '用戶名不能為空!' }); if ($scope.frmLogin.txtPwd.$invalid) $scope.alerts.push({ type: 'danger', msg: '密碼不能為空!' }); if ($scope.alerts.length) return; $scope.alerts = [{ type: 'success', msg: '登錄成功' }]; }; $scope.closeAlert = function (index) { $scope.alerts.splice(index, 1); }; };
當用戶名密碼未填寫或者表單正確的情況下,點擊提交按鈕的時候會出現以下2種情況,如圖:
當我們點擊X的時候(多次點擊的時候會出現多個提示,別在意這個小問題,^_^),會調用closeAlert方法,並根據$index刪除alerts數組內對應的元素,這時候綁定的視圖就會自動刷新,不需要手動去操作這些元素,這里要注意的主要有3個地方:1、ng-app="login"是不能缺少的,除非你要手動啟動ng;2、開頭的angular.module('login', ['ui.bootstrap']);的意思是注冊login模塊且該模塊需要對ui-bootstrap的引用(否則無法顯示alert的效果);3、HomeLoginController方法的參數$scope是不能重命名成其他名字,否則ng會報錯。
如果我們想要讓彈出來的Alert自己消失怎么辦呢?一開始的時候,大家可能會跟我一樣,會嘗試使用setTimeout函數去直接從$scope.alerts數組內將對應的元素移除掉,然后等待着視圖將Alert移除掉,但是最后會發現一點作用都沒有,因為視圖數據是在ng內部進行控制的,需要使用它提供的機制去處理,視圖才會跟着數據發生變化,這里需要使用$timeout去完成以上的操作,代碼改動如下:
//其他代碼略 $scope.submit = function () { if ($scope.frmLogin.txtName.$invalid) addAlert({ type: 'danger', msg: '用戶名不能為空!' }); if ($scope.frmLogin.txtPwd.$invalid) addAlert({ type: 'danger', msg: '密碼不能為空!' }); if ($scope.alerts.length) return; addAlert({ type: 'success', msg: '登錄成功' }); }; function addAlert(alert) { $scope.alerts.push(alert); $timeout(function () { angular.forEach($scope.alerts, function (a, i) { if (alert != a) return; $scope.alerts.splice(i, 1); }); }, 500); };
寫到這里已經把大致該出現的效果都做出來了,現在的問題是這個腳本是直接寫在頁面上的,那么怎么樣通過seajs來加載呢?這里就需要用到angular的手動加載模式了,首先需要對html進行修改要先將ng-app給移除掉,不然ng會自動加載,由於已經將腳本轉移到js文件內了,無法找到HomeLoginController方法ng會拋出錯誤,使用seajs后的代碼如下:
//頁面 seajs.use('home-login'); //腳本文件 this.define(function (require, exports, module) { angular.module('home.login', ['ui.bootstrap']).controller('HomeLoginController', function ($scope, $timeout) { //原本HomeLoginController方法內的代碼,這里就不重復貼出了 }); angular.bootstrap($('[name=frmLogin]'), ['home.login']); });
從代碼中可以看到首先要注冊模塊home.login這個名字是可以任意的,但是必須跟bootstrap內引用的模塊對應,然后我們創建頁面上需要的Controller(名字一樣得對應),並使用ng的bootstrap來手動啟動。
那么第一篇結合bootstrap + angularjs + seajs就到這里了,如果有任何錯誤請各位指出,謝謝,^_^!