關於angular的教程,學習了一下angular的ui-router和ng-grid這兩個模塊,順便模仿着做了一個小小的東西。
代碼已經上傳到github上,地址在這里https://github.com/Songyj-225/angular。
有興趣的小伙伴可以看看,目前還不會php只有前端的部分,那么然后這里我們就先來了解一下這兩個模塊的用法
我們先來說說ui-router這個模塊,這個模塊主要是用來實現深層次的路由的。其實angular有個內置的指令ng-route,如果在項目中沒有嵌套問題的話,那么用這個指令來實現頁面之間的跳轉也還是蠻方便的,但是他的短板就在於,他拿深層次的嵌套路由沒有任何辦法。那么首先,我們要使用這個模塊我們就需要把他給下載下來。
UI-Router被認為是AngularUI為開發者提供的最實用的一個模塊,它是一個讓開發者能夠根據URL狀態或者說是'機器狀態'來組織和控制界面UI的渲染,而不是僅僅只改變路由(傳統AngularJS應用實用的方式)。該模塊為開發者提供了很多最視圖(view)額外的控制。開發者可以創建嵌套分層的視圖、在同一個頁面使用多個視圖、讓多個視圖控制某個視圖等更多的功能。即使是非常復雜的web應用,UI-Router也可以極佳地駕馭
下載地址在這里http://www.bootcdn.cn/angular-ui-router/。
下載下來之后,我們就可以把它導入進我們的項目中了,這里要注意下,因為這個模塊式基於angular的,所以在這之前,我們還需要導入angular的js文件。這個可以在angular的官網去下載。
那么在上面的准備工作都做完了之后,我們就可以來動手寫我們的代碼了。
index.html
<body> <div ui-view ></div> </body>
這里有一點要注意下,div里面添加的屬性是ui-view
app.js
var app = angular.module('routerApp',['ui.router','ngGrid', 'BookListModule', 'BookDetailModule','Bookadd']); /** * 由於整個應用都會和路由打交道,所以這里把$state和$stateParams這兩個對象放到$rootScope上, * 方便其它地方引用和注入。 * 這里的run方法只會在angular啟動的時候運行一次。 * $rootScope * $state * $stateParams **/ app.run(function($rootScope,$state,$stateParams){ $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; }); /** * 配置路由.config * 這里采用的是ui-router這個路由,而不是原生的ng-router路由 * ng原生的路由不能支持嵌套視圖,所以這里必須使用ui-router; * $stateProvider * $urlRouterProvider **/ app.config(function($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise('/index');//沒有任何值得情況下去到index $stateProvider.state('index',{//登陸頁面 url:'/index', templateUrl:'tpls/loginForm.html' }).state('booklist',{//后台界面 url: '/{bookType:[0-9]{1,4}}', views: { //注意這里的寫法,當一個頁面上帶有多個ui-view的時候如何進行命名和視圖模板的加載動作 '': { templateUrl: 'tpls/bookList.html' }, 'bookgrid@booklist': { templateUrl: 'tpls/bookGrid.html' } } }).state('addbook', { url: '/addbook', views: { //注意這里的寫法,當一個頁面上帶有多個ui-view的時候如何進行命名和視圖模板的加載動作 '': { templateUrl: 'tpls/bookList.html' }, 'addbook@addbook':{ templateUrl: 'tpls/addBookForm.html' } } }) .state('bookdetail', { url: '/bookdetail/:bookId',//注意這里在路由中傳參數的方式 views: { //注意這里的寫法,當一個頁面上帶有多個ui-view的時候如何進行命名和視圖模板的加載動作 '': { templateUrl: 'tpls/bookList.html' }, 'seebook@bookdetail':{ templateUrl: 'tpls/bookDetail.html' } } }) })
1、是在進行嵌套的時候,我這里最外層是booklist部分,然后里面嵌套了seebook和addbook和bookgird部分,我們需要注意下這里的寫法。
2、當我們需要根據選擇不同打開不同的內容時,也就是需要向下一個頁面傳參數,我這里是細節部分,我們也需要多注意下這里的寫法。
3、在我們利用angular.module創建一個app應用的時候,我們需要在里面導入ui.router模塊,另外我們自己創建的一些模塊也需要在這里導入進去。
4、我們這里使用$stateProvider來配置路由了,而不是$routeProvider了,還有就是這里使用的state而不是when。
這里吧路由配置好了之后,剩下的就是寫tpls中各個部分的代碼了,這里就不做過多的介紹,這里最重要的就是路由的配置。
好了下面我們再來看看ng-grid的用法,這里是下載地址http://www.bootcdn.cn/ng-grid/。
booklist.html
<!-- 導航 --> <nav class="navbar navbar-inverse lan navbar-static-top" role="navigation"> <div class="navbar navbar-inverse lan navbar-fixed-top" role="navigation"> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#leftnav" > <span class="sr-only"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">圖書管理系統</a> </div> <ul class="nav navbar-nav navbar-right maright"> <li><a><span class="badge colorred">5</span></a></li> <li><a href="#"><span class="glyphicon glyphicon-off"></span> 退出</a></li> </ul> <!-- 左側欄 --> <div class="navbar-collapse" id="leftnav" ng-controller="booklist"> <ul class="nav"> <li> <a data-target="#list" class="coloractive" data-toggle="collapse" aria-expanded="true"> <span class="glyphicon glyphicon-book"></span> 書籍類型 <span class="glyphicon glyphicon-chevron-right pull-right"></span> </a> <ul id="list" class="nav collapse listbg in" aria-expanded="true"> <li ng-repeat="book in booklist" ui-sref = "booklist({bookType:{{book.id}}})"> <a > <span class="glyphicon {{book.img}}"></span> {{book.name}}</a> </li> </ul> </li> </ul> </div> </div> </nav> <!-- 右側 --> <div class="page_mian"> <div class="container"> <div class="row "> <div ui-view="bookgrid" class="col-xs-12"> <!--書籍列表加載中...--> </div> <div ui-view="addbook" class="col-xs-12"> <!--添加書籍--> </div> <div ui-view="seebook" class="col-xs-12"> <!--查看書籍--> </div> </div> </div> </div>
主要是右側部分,操作顯示都在右側替換
controller.js
/*** * 這里是登陸模塊 * ***/ app.controller('validateCtrl',function($scope){ $scope.user={ email:'', password:'' }; $scope.arrs={ email:'song@126.com', password:'123456' }; $scope.compare = function(user){ $scope.user= user; $scope.same = angular.equals($scope.user.email,$scope.arrs.email)//對比 $scope.same1 = angular.equals($scope.user.password,$scope.arrs.password)//對比 console.log($scope.same); console.log($scope.same1); console.log($scope.user.email); if($scope.same == false){ $scope.user.email='用戶名不正確'; console.log(user.email); }; if($scope.same1 == false){ $scope.user.password=''; console.log(user.password); } } }); /** *后台界面 **/ app.controller('booklist',function($scope,$http){ $scope.booklist ={}; $http.get('data/bookslist.json') .success(function (item){ $scope.booklist = item; console.log($scope.booklist) }); }); /** * 這里是書籍列表模塊 **/ var bookListModule = angular.module("BookListModule", []); bookListModule.controller('BookListCtrl', function($scope, $http, $state, $stateParams) { //以下是分頁內容 $scope.filterOptions = { filterText: "", useExternalFilter: true }; $scope.totalServerItems = 0; $scope.pagingOptions = { pageSizes: [5, 10, 20], pageSize: 5, currentPage: 1 }; $scope.setPagingData = function(data, page, pageSize) { var pagedData = data.slice((page - 1) * pageSize, page * pageSize); $scope.books = pagedData; $scope.totalServerItems = data.length; if (!$scope.$$phase) { $scope.$apply(); } }; //這里可以根據路由上傳遞過來的bookType參數加載不同的數據 console.log($stateParams); $scope.getPagedDataAsync = function(pageSize, page, searchText) { setTimeout(function() { var data; if (searchText) { var ft = searchText.toLowerCase(); $http.get('../src/data/books' + $stateParams.bookType + '.json')//通過傳值調用不同json .success(function(largeLoad) { data = largeLoad.filter(function(item) { return JSON.stringify(item).toLowerCase().indexOf(ft) != -1; }); $scope.setPagingData(data, page, pageSize); }); } else { $http.get('../src/data/books' + $stateParams.bookType + '.json') .success(function(largeLoad) { $scope.setPagingData(largeLoad, page, pageSize); }); } }, 100); }; $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage); $scope.$watch('pagingOptions', function(newVal, oldVal) { if (newVal !== oldVal && newVal.currentPage !== oldVal.currentPage) { $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText); } }, true); $scope.$watch('filterOptions', function(newVal, oldVal) { if (newVal !== oldVal) { $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage, $scope.filterOptions.filterText); } }, true); $scope.gridOptions = { data: 'books',//表格中顯示的數據來源 rowTemplate: '<div style="height: 100%"><div ng-style="{ \'cursor\': row.cursor }" ng-repeat="col in renderedColumns" ng-class="col.colIndex()" class="ngCell ">' + '<div class="ngVerticalBar" ng-style="{height: rowHeight}" ng-class="{ ngVerticalBarVisible: !$last }"> </div>' + '<div ng-cell></div>' + '</div></div>', multiSelect: false,//是否能多選 enableCellSelection: true, //是否能選擇單元格 enableRowSelection: false,//是否能選擇行 enableCellEdit: true,//是否能修改內容 enablePinning: true, //是否被鎖住了 columnDefs: [{ field: 'index',//這里是數據中的屬性名 displayName: '序號', //這里是表格的每一列的名稱 width: 60,//表格的寬度 pinnable: false, sortable: true//是否能排序 }, { field: 'name', displayName: '書名', enableCellEdit: true }, { field: 'author', displayName: '作者', enableCellEdit: true, width: 220, pinnable: true, sortable: true }, { field: 'pubTime', displayName: '出版日期', enableCellEdit: true, width: 120 }, { field: 'price', displayName: '定價', enableCellEdit: true, width: 120, cellFilter: 'currency:"¥"' }, { field: 'bookId', displayName: '操作', enableCellEdit: false, sortable: false, pinnable: false, cellTemplate: '<div><a ui-sref="bookdetail({bookId:row.getProperty(col.field)})" id="{{row.getProperty(col.field)}}">詳情</a></div>' }], enablePaging: true,//是否能翻頁 showFooter: true,//是否顯示表尾 totalServerItems: 'totalServerItems',//數據的總條數 pagingOptions: $scope.pagingOptions,//分頁部分 filterOptions: $scope.filterOptions,//數據過濾部分 }; }); /** * 這里是書籍詳情模塊 * @type {[type]} */ var bookDetailModule = angular.module("BookDetailModule", []); bookDetailModule.controller('BookDetailCtrl', function($scope, $http, $state, $stateParams) { console.log($stateParams); }); var bookadd = angular.module('Bookadd',['ngAnimate', 'ngSanitize','ui.bootstrap']); bookadd.controller('Bookaddctrl',function($scope,$http,$state, $stateParams){ function abf(){ $scope.userInfo={};//空 $scope.userInfo.dt = new Date();//日歷 $scope.popup2 = { opened: false }; $scope.open2 = function() { $scope.popup2.opened = true; }; $scope.sites=[ //下拉列表 {id:0,site:'計算機'}, {id:1,site:'金融'}, {id:2,site:'哲學'}, {id:3,site:'歷史'} ]; $scope.userInfo.zw = '1';//默認選中一個 }; abf();//執行 $scope.geto =function(user){ $scope.userInfo = user console.log($scope.userInfo.dt.toISOString().slice(0,10))//日期格式化 $http({ url:'data/books5.json', method:'POST', data:$scope.userInfo, data:JSON.stringify($scope.userInfo) }).success(function(da){ console.log(da); // console.log($stateParams); window.history.back(); }); }; $scope.setFormData = function(){//清空 abf(); } })
這里最重要的就是$scope.gridOptions這一塊了,同時我們需要多注意下最后一個詳細攻略里面,傳參數的寫法。
下面附上幾張效果圖: