很早之前就大概看過一點angualrjs,可是沒有項目,一直沒有進行下去,就是乾巴巴的看着,過了一段時間發現什麼也不記得了。javascript
來yulebaby個人第一個後臺管理是用easyui作的,作完那個之後發現有不少侷限,由於easyui裏面都是內嵌了iframe,當時在iframe中操做js的時候我真的是頭疼想死呀。而後我就想着仍是用angualr來弄吧,這也是如今先後臺分離的方向,而後就有了接下來那些有趣的事情。html
Angularjs雖然很強大,可是你要是掌握了其中這幾大塊其實也是那麼回事,雙向數據綁定,做用域,指令,控制器,服務,路由,過濾器,我此次項目中也就用到了這幾塊的內容,不過接觸的也不復雜,都是些基本的。vue
首先我大體說一下咱們這個後臺管理的原型和需求。java
咱們的後臺管理分3種角色,不過目前咱們只作了2種,設備助理和財務,設備助理主要是用來添加設備,生成設備銷售單的,還有就是設備銷售單管理和設備銷售單退單管理;財務主要用來管理設備庫的,財務也有設備銷售單管理和設備銷售單退單管理的權限,只是有些是可看不可操做的,具體的不一樣的角色有不一樣的權限這個就不細說了......jquery
並且咱們在作權限控制這塊還用到了監聽路由改變,而後將沒有權限的url進行攔截,這個主要是由於,咱們的後臺是java,他們用了一個古老的框架,因爲後臺框架的限制,咱們的angualr項目不能放到他們的webinfor下面,單獨拿出來之後,權限什麼的就不受他們控制了,因此當時咱們在沒有辦法的狀況下就用了一個比較笨的方法來控制權限了,具體以下:web
app.run(function ($rootScope, $state) { $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams, options){ function getCookie(name){ var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)){ return (arr[2]); } else{ return null; } } var roleId = getCookie('roleId'); var caiwu = ['error', 'router', 'index', 'equipSaleManageAllCw','equipSaleManageAllCwdefult','equipSaleManageDetailCw','equipReturnAllCw','equipReturnDetailCw','equipListCw','equipPackageCw','equipClassCw','equipDetailsCw','addEquipmentCw','equipPackageDetailsCw','equipClassDetailsCw','equipNewClassCw']; var sbzli = ['error', 'router', 'index', 'equipAdd','equipSaleManageAll','equipSaleManageAlldefult','equipSaleManageDetail','equipSaleManagethDetail','equipReturnAll','equipReturnDetail']; if(roleId == 23){ if(caiwu.indexOf(toState.name) < 0){ event.preventDefault(); $state.go('error'); } } if(roleId == 27){ if(sbzli.indexOf(toState.name) < 0){ event.preventDefault(); $state.go('error'); } } }) })
而後這個項目中有個比較麻煩的就是分頁和圖片上傳了,首先說一下分頁,咱們的分頁是本身分裝了一個指令,ajax
<div class="bby-page-box" ng-show="page.count > 1"> <a href="javascript: void(0);" ng-show="page.pageNo!==1" ng-click="queryData(page.pageNo - 1)">上一頁</a><!-- --><a href="javascript: void(0);" ng-show="page.pageNo - 4 > 0 && page.count > 7" ng-click="queryData(1)">1</a><!-- --><a href="javascript: void(0);" ng-show="page.pageNo - 4 > 0 && page.count > 7" class="bby-page-ellipsis">…</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 6)" ng-show="page.pageNo - 6 > 0 && page.count <= 7">{{page.pageNo - 6}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 5)" ng-show="page.pageNo - 5 > 0 && page.count <= 7">{{page.pageNo - 5}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 4)" ng-show="page.pageNo - 4 > 0 && page.count <= 7">{{page.pageNo - 4}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 3)" ng-show="page.pageNo - 3 > 0">{{page.pageNo - 3}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 2)" ng-show="page.pageNo - 2 > 0">{{page.pageNo - 2}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo - 1)" ng-show="page.pageNo - 1 > 0">{{page.pageNo - 1}}</a><!-- --><a href="javascript: void(0);" class="active">{{page.pageNo}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 1)" ng-show="page.pageNo + 1 <= page.count">{{page.pageNo + 1}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 2)" ng-show="page.pageNo + 2 <= page.count">{{page.pageNo + 2}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 3)" ng-show="page.pageNo + 3 <= page.count">{{page.pageNo + 3}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 4)" ng-show="page.pageNo + 4 <= page.count && page.pageNo + 4 < 8">{{page.pageNo + 4}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 5)" ng-show="page.pageNo + 5 <= page.count && page.pageNo + 5 < 8">{{page.pageNo + 5}}</a><!-- --><a href="javascript: void(0);" ng-click="queryData(page.pageNo + 6)" ng-show="page.pageNo + 6 <= page.count && page.pageNo + 6 < 8">{{page.pageNo + 6}}</a><!-- --><a href="javascript: void(0);" ng-show="page.count >= page.pageNo + 4 && page.count > 7" class="bby-page-ellipsis">…</a><!-- --><a href="javascript: void(0);" ng-show="page.count >= page.pageNo + 4 && page.count > 7" ng-click="queryData(page.count)">{{page.count}}</a><!-- --><a href="javascript: void(0);" ng-show="page.pageNo !== page.count" ng-click="queryData(page.pageNo + 1)">下一頁</a><!-- --><span> 到第<!-- --><input type="text" ng-model="gonum" placeholder="1" ng-change="ongonum()"><!-- -->頁<!-- --><a href="javascript: void(0);" ng-click="queryData(gonum)">肯定</a> </span><!-- --><select ng-model="pageNumber" ng-options="pageNumber.text for pageNumber in pageNumList" ng-init="pageNumber = pageNumList[0]"> </select> <span>共{{page.count}}頁{{page.pageCount}}條</span> </div>
app.directive('pagination', function(){ return { controller: function($scope, $element, $attrs, $transclude, $http) { /* 每頁顯示條數 */ $scope.pageNumList = [{value: 10, text: 10},{value: 20, text: 20},{value: 30, text: 30},{value: 50, text: 50},{value: 100, text: 100}]; /* 監聽每頁顯示條數 */ $scope.$watch('pageNumber', function (n, o) { if(n.value !== o.value){$scope.queryData(1);} }) $scope.queryData = function (pegeNo, query) { $scope.gonum = '';//點擊確認調轉頁數之後清空輸入框 $scope.queryCriteria = query !== undefined ? query : $scope.queryCriteria; $scope.pageNo = pegeNo !== undefined ? pegeNo : 1; try{ $scope.param = $scope.pageNumber.value ? $scope.pageNumber.value : 10; }catch (e) { $scope.param = 10; } $scope.pageNo = pegeNo ? pegeNo : 1; var params = { pageNo: $scope.pageNo, pageSize: $scope.param }; if($scope.queryCriteria){ for(var v in $scope.queryCriteria){ params[v] = $scope.queryCriteria[v]; } } $scope.$emit('loading', {}); $scope.loading = true; $http({ url: $scope.URL, method: 'get', params: params }).then(function (res) { $scope.page = res.data; $scope.page.count = Math.ceil(res.data.pageCount/res.data.pageSize); $scope.$emit('items', res.data); },function (e) { $scope.loading = false; $scope.$emit('items', {code: 1, message: "網絡異常,請刷新頁面"}); }) } $scope.queryData(1,$scope.defult); $scope.$on('query', function (e, d) { $scope.queryData(1, d); }) $scope.$emit('onload', {}); }, restrict: 'EA', templateUrl: 'script/directives/directiveView/pagination.html', replace: true, link: function (scope, ele, attrs){ scope.ongonum = function () { if(!scope.gonum){return;} var vue = parseInt(scope.gonum.replace(/[^\d]/g,'')); if(!vue){scope.gonum = '1';return;} if(vue > scope.page.count){ scope.gonum = scope.page.count; }else if(vue < 1){ scope.gonum = 1; }else{ scope.gonum = vue; } } } }; });
分頁指令封裝好了,而後在html頁面調用就直接寫上<pagination></pagination>這個就行了,指令調用的方式有4種,EACM,元素,屬性,類名,註釋。json
而後在控制器中使用直接接收指令傳輸過來的數據:數組
$scope.$on('items', function (e, data) { $scope.loading = false; if(data.code == 1000){ if(data.data){ $scope.items = data.data; }else{ $scope.items = []; } }else{ $scope.items = []; $scope.promptBlen = true; $scope.promptText = data.message; } $scope.init=function(){ angular.forEach($scope.items, function(data){ if(data.status == 7){ data.returnRule=true; //把returnRule綁定到每一個對象顯示退貨按鈕 }else{ data.returnRule=false; } }); } $scope.init(); $scope.flag=true; });
這裏要直接注意下,指令與控制器之間的通訊方式,還有控制器用控制器直接的通訊方式,反正我就是記住一點,通訊用$on來接收數據,若是是父控制器向子控制器傳播數據就是廣播,$broadcast,若是是子控制器向父控制器傳送數據就是$emit,向上傳遞數據。這個很重要,若是記起來比較困難的,再去百度下就行了。服務器
分頁的成品以下:
而後還有就是圖片上傳:
咱們的圖片上傳採用的是能夠單張上傳,也能夠多張上傳的,可是不能超過6張,最開始準備在網上找個angualr圖片上傳的插件,可是後來仍是用jquery來寫了,js具體以下:
app.factory('$preview', function () { // getUrlFn(window.location.href) var getUrlFn = function(str){ var oaPosition = str.indexOf('oa'); return str.substring(0,oaPosition+2); } return { upfile: function (id, status, see){ window.delParent = ''; var imgContainer = $("#photoItemsBox"); //存放圖片的父親元素 var data = {}; var numUp; if(status == 0){ data.equOrderNo = id }else{ data.orderReturnNo = id; } if(see){ $('.z_file').hide(); } $.ajax({ url: getUrlFn(window.location.href) + '/equipment/equImgUpload/queryImgs.do', type: 'get', data: data, dataType: 'json', success: function (data) { if(data.code == 1000){ if(data.data!=undefined && data.data!=null && data.data.length>0){ for(var i = 0; i < data.data.length; i++){ (function (){ var box = $('<div class="up-section"></div>'); var closeBg = $('<a href="javascript: void(0);" class="close-upimg">×</a>'); var imgThis = $('<img class="up-img" src="'+ data.data[i].imgUrl +'" />'); box.append(imgThis); var input = $('<input id="imgIds" name="imgIds" value="'+ data.data[i].id +'" type="hidden"/>'); if(!see){ box.append(closeBg); box.append(input); } imgContainer.append(box); })() } } numUp = $('.up-section').length; if(numUp < 6 && !see){ $(".z_file").show(); }else{ $(".z_file").hide(); } } } }) var defaults = { fileType : ["jpg","png","gif","jpeg"], // 上傳文件的類型 fileSize : 1024 * 1024 * 5 }; /*點擊圖片的文本框*/ $("#file").change(function(){ var idFile = $(this).attr("id"); var file = document.getElementById(idFile); var fileList = file.files; //獲取的圖片文件 var imgArr = []; //遍歷獲得的圖片文件 var numUp = imgContainer.find(".up-section").length; var totalNum = numUp + fileList.length; if(fileList.length > 6 || totalNum > 6 ){ alert("圖片超出6張,請刪除多餘圖片後再上傳"); }else if(numUp < 6){ fileList = validateUp(fileList); var formData = new FormData(); for(v in data){ formData.append(v, data[v]); } for(var i = 0; i < fileList.length; i++){ var imgUrl = window.URL.createObjectURL(fileList[i]); imgArr.push(imgUrl); var OrderImg = 'OrderImg'+(i+1); var OrderImgName = 'OrderImgName'+(i+1); formData.append(OrderImg, fileList[i]); formData.append(OrderImgName, fileList[i].name); (function (){ var box = $('<div class="up-section"></div>'); var loading = $('<div class="line-scale"><div></div><div></div><div></div><div></div><div></div></div>'); box.append(loading); var closeBg = $('<a href="javascript: void(0);" class="close-upimg">×</a>'); box.append(closeBg); var imgThis = $('<img class="up-img" src="'+ imgArr[i] +'" />'); box.append(imgThis); var input = $('<input id="imgIds" name="imgIds" type="hidden"/>'); box.append(input); imgContainer.append(box); })() } $.ajax({ url: getUrlFn(window.location.href) + "/equipment/equImgUpload/addImgs.do", type: 'POST', cache: false, data: formData, processData: false, contentType: false, success: function(data) { if(data.code == 1000){ $('.line-scale').hide(); for(var i = 0; i < data.data.length; i++){ imgContainer.children('div').eq(i).find('.up-img').attr('src', data.data[i].imgUrl); imgContainer.children('div').eq(i).find('input').val(data.data[i].id); } } console.log("成功"); }, error: function(e) { console.log('失敗') } }); } numUp = imgContainer.find(".up-section").length; if(numUp >= 6){ $(this).parent().hide(); } //input內容清空 $(this).val(""); }); $("body").on("click",'.close-upimg',function(){ event.preventDefault(); event.stopPropagation(); $(".works-mask").show(); window.delParent = $(this).parent(); deleteId = $(this).siblings('input').val(); }); $(".wsdel-ok").click(function(){ $(".works-mask").hide(); var dataD = data; dataD.imgIds1 = deleteId $.ajax({ url: getUrlFn(window.location.href) + '/equipment/equImgUpload/delete.do', type: 'get', data: dataD, dataType: 'json', success: function (data) { if(data.code == 1000){ var numUp = window.delParent.siblings().length; if(numUp < 7){ $(".z_file").show(); } window.delParent.remove(); }else{ alert(data.message); } }, error: function (e) { console.log('請求失敗'); } }) }); $(".wsdel-no").click(function(){ $(".works-mask").hide(); }); function validateUp(files){ var arrFiles = [];//替換的文件數組 for(var i = 0, file; file = files[i]; i++){ //獲取文件上傳的後綴名 var newStr = file.name.split("").reverse().join(""); if(newStr.split(".")[0] != null){ var type = newStr.split(".")[0].split("").reverse().join(""); if(jQuery.inArray(type, defaults.fileType) > -1){ // 類型符合,能夠上傳 if (file.size >= defaults.fileSize) { alert('您這個"'+ file.name + '-----' + file.size +'"文件大小過大'); } else { // 在這裏須要判斷當前全部文件中 arrFiles.push(file); } }else{ alert('您這個"'+ file.name +'"上傳類型不符合'); } }else{ alert('您這個"'+ file.name +'"沒有類型, 沒法識別'); } } return arrFiles; } } } })
咱們是封裝了一個服務,而後在頁面引入html
<!--上傳圖片 --> <div class="bby-form-item" ng-show="statu!=1" class="upPhoto"> <label for="" class="bby-form-label">交款憑證圖:</label> <div class="bby-input-block"> <div class="z_photo" id="photoItemsBox"></div> <div class="z_file"> <label for="file" class="add-img">點擊上傳圖片</label> <input type="file" name="file" id="file" accept="image/jpg,image/jpeg,image/png,image/gif" multiple /> </div> <div class="mask works-mask"> <div class="mask-content"> <p class="del-p">肯定要刪除該圖片嗎?</p> <p class="check-p"><span class="del-com wsdel-ok">肯定</span><span class="wsdel-no">取消</span></p> </div> </div> </div> </div>
而後在控制器依賴注入這個服務,直接調用就行了
上傳圖片成品以下:(包括顯示圖片,上傳圖片,點擊查看大圖,刪除圖片)
這裏,咱們的圖片服務器出來點問題,因此圖片失效了,線上的是沒有問題的。
反正作這個項目的難點和思路大概也就這麼些,第一次用angualr,還有不少東西作的很粗糙,今天寫的博客也稀裏糊塗的,思路不太清晰,就是隨便寫寫,記錄下本身的成長,將來的路還很長,慢慢來.......