angularjs和ajax的結合使用 (三)
轉眼九月份了,忙忙碌碌 發現今年還沒開過張,寫一篇吧。
15年在空閑時就倒騰過angularjs那玩意兒 ,覺得還是挺好的,李金龍那厚厚的一本書,只不過沒有系統化應用。最主要的是原來有一個東西沒有用到 那就是路由。在中衡的時候看到黃國文同誌用那種全ajax的方式做的網站,那感覺。。。現在公司竟然也這麽做,全是JS 寫成一大坨跟屎一樣的 js這玩意兒是弱類型的 調也不好調 對它完全沒好感 看到那些js代碼都快吐了,ajax有那麽好麽 ,整個頁面你不還是得刷新 ,快得了多少 頁面還不容易控制。現在看了李師傅搞的 黃國文同誌那也就那麽回事兒而已。相對來說用angularJS更好 ,總之現在很討厭JS。好吧整都整了也不抱怨了 ,我們還是一起來學習下他吧。這段時間做的工作是易電小跟班 年初在小跟班分支上做了易電設備移動端。 用的比較多的是 angularjs1.x ,今天將分享他的使用 和一些技巧。
基本使用:
angularJS的官方網站是 https://angularjs.org/ VisualStudio 都把angularjs指令的智能提示都集成進來了,足以證明還是有一定認可度的。angularJS的基本使用前兩章已經講過了 沒有太多說的,但是我們還是來復習下:
引入angularjs 和ui-router.js
1 <script src="../WebTools/angular.min.js"></script> 2 <script src="../WebTools/angular-ui-router.min.js"></script>
然後界面上定義app和視圖作用域 ,也就是 ng-app="" 和 ng-controller
1 <html xmlns="http://www.w3.org/1999/xhtml" ng-app="xiangapp"> 2 <head> 3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 4 <title></title> 5 <script src="\WebTools\jquery-2.0.2.min.js"></script> 6 <script src="\WebTools\angular.min.js"></script> 7 <script src="\WebTools\angular-route.js"></script> 8 </head> 9 <body> 10 <div ng-controller="maincontroller"> 11 </div> 12 13 </body> 14 </html>
Angularjs是一個mvvm框架 ,核心理念是 讓界面上產生一個個領域 讓這些領域跟js後臺聯系起來。讓界面的app作用域 controller作用域這些 跟 後臺的數據產生關聯 ,但同時 這些作用域又是 可以嵌套的 controller可以嵌套的,上層作用域的東西 可以被下層調用 以達到靈活運用的目的。也不知道我到底講清楚沒 - -!感覺自己講這些有點語無倫次的。
然後就是把前面指定的界面部分綁定到作用域 並註入ui-router ,它的意義是把界面作用域的部分 跟js綁定 並給js一個“”把柄“” 以便控制數據 ,告訴js這部分界面的數據歸你這個scope管。說了這麽多還是紅色部分字的意思。雖然代碼還是差不多的代碼,但是自己時切切實實的感覺 應用比15年時候的那種照貓畫虎更實在些了,理解也更深刻些了。非要怎麽說嘛 意會。
把界面指定部分綁定到js作用域 並註入ui-router 然後定義路由規則:
1 var app = angular.module("xiangapp", ["ui.router"]); 2 3 app.config([‘$stateProvider‘, ‘$urlRouterProvider‘, function ($stateProvider, $urlRouterProvider) { 4 $urlRouterProvider.otherwise(‘/main‘); 5 6 $stateProvider 7 .state(‘home‘, { 8 url: ‘/home‘, 9 views: { 10 "body": { 11 templateUrl: ‘home.html‘, 12 controller: ‘homecontroller‘ 13 } 14 } 15 }) 16 .state(‘about‘, { 17 url: ‘/about‘, 18 views: { 19 "body3": { 20 templateUrl: ‘about.html‘, 21 controller: ‘aboutcontroller‘ 22 } 23 } 24 })
註入確實是angularjs的一個特色,註意上面已經拿到一個app的把柄了,只要拿到這個app的把柄我們就可以為所欲為了,比如上面的配置路由,做一些前置配置操作。總之註入這個工具類後 我們就可以在controller裏使用它了,這個後面再說,總之是各種註入 ,你可以理解為angular裏一種比較方便的套路,註入一個工具服務類:
1 var app = angular.module("xiangapp", ["ui.router"]); 2 //註入一個util 工具類 3 app.service("Util", function ($http, $rootScope) { 4 this.showMsg = function (msg) { 5 alert(msg); 6 }; 7 });
最後的最後其實就是一些搬磚工作 就是編寫路由到的各個子模塊定義的controller ,在裏面編寫各個頁面自管區域的邏輯。註意 註意 註意 重要的事情說三遍 ,依然是通過上面app這個重要的把柄 來編寫各個controller邏輯,比如這裏我們編寫mainController 其他的也類似:
1 app.controller("maincontroller", function ($scope, Util) { 2 $scope.message = "主controller初始化信息"; 3 Util.showMsg("UtilService調用"); 4 });
我們也可以把一些公共的東西放到 $rootscope裏面去。AngularJS的作用域可以是一個嵌套結構,controller嵌controller,下層作用域即使沒有寫對應的函數,也可以調用上層的函數。
其實angularjs 自帶了 ngroute 路由(也要另外再引入js) 為甚我們還要再使用ui-router,Ui-router路由方式 比angular自帶的路由方式好的地方:
通過$state和$stateparameter 達到靈活的狀態跳轉
支持嵌套視圖(基本用不上)
ui-router它最大的作用是將web界面的設計分塊了
冒泡事件和廣播事件
angularJS裏還有個很有用的東西就是事件觸發,各個controller可以嵌套 也可以相互獨立 他們之間可以通過事件觸發的機制來進行消息傳遞和觸發某個動作,可能會說不是controller可以嵌套 子controller可以直接調用主controller的函數麽 ,是的 但是只能直接的方式調一次你上層controller的函數,並且形不成事件 響應 這種的結構 會導致結構混亂,所以 ,該用啥就用啥。響應冒泡事件 和響應廣播事件 代碼是一樣的:
1 $scope.$on("toparentEvent", function (event, args) { 2 alert(args.message + "ggg"); 3 });
廣播事件是主controller往子controller傳遞依次觸發所有響應了此事件的代碼,冒泡事件是從子controller往上層傳遞依次觸發響應了此事件的代碼。 觸發廣播事件 和觸發冒泡事件的代碼有所不同,發動冒泡事件:
1 //往父級傳遞事件 2 $scope.toparentEvent = function () { 3 $scope.$emit("toparentEvent", { message: "我是子Controller的消息" }); 4 }
發動廣播事件:
1 //廣播 2 $scope.boardCastEvent = function () { 3 $scope.$broadcast("boardCastEvent", { message: "我是廣播消息" }); 4 }
promise調用:
angularJS裏的另一個大殺器,那就是promise ,這到底是個神馬玩意兒,在網上說怎麽怎麽ajax回調嵌套 陷入回調地獄,巴拉巴拉 就是沒給個ajax promise回調的例子出來 ,首先promise的詳細說明這裏有一篇教程:https://www.cnblogs.com/ZengYunChun/p/6438330.html
使用的基本思想是 首先引入$q 使用defer() 獲取promise對象 ,在異步調用正常結束的地方 也就是ajax回調成功的地方resolved() , 在函數結束的地方return xx.promise 即可 ,這個套路有點像多線程同步的調調。下面是我的一個ajax鏈式調用例子:
1 var defer1 = $q.defer(); 2 $http.get("/api/Class1/GetTest").success(function (res) { 3 setTimeout(function () { 4 alert("aa"); 5 defer1.resolve(); 6 }, 3000); 7 }); 8 9 var promise1 = defer1.promise; 10 11 var defer2 = $q.defer(); 12 promise1.then(function (res) { 13 $http.get("/api/Class1/GetTest").success(function (res) { 14 setTimeout(function () { 15 alert("bb"); 16 defer2.resolve(); 17 }, 2000); 18 }); 19 }); 20 21 var promise2 = defer2.promise; 22 23 promise2.then(function (res) { 24 alert("cc"); 25 });
看就是這種方式 通過defer.promise 得到一個同步句柄 ,然後此promise.then裏面再處理同步,可一直寫到promiseN ,看果然沒有形成嵌套 。 但是他大爺的 感覺怪怪的。
每次得到一個promise用於在下一個then裏進行同步。能說的就這麽多了。又得到一個promise進行下一次同步 如此往復。
當然如果你玩兒熟了,還可以玩兒子路由,其它各種更靈活 的應用,反正最基本的就是這些了,其它全靠你的創造。總之angularJS就是通過這些手段 進行靈活 並合理的歸並 進行業務邏輯 和數據處理。
一些心得:
並不是界面最外面一層一定要有菜單 跳轉,可以是一個空白。
路由機制 history.back()。從上至下進行分支跳轉 ,history.back() 則相當於在跳轉的樹裏回到了上一級 。(對於手機端app的跳轉需求)這是一個比較完美的路由機制 。
並不一定要是從頭至尾ajax的 ,頁面是可以刷新的 ,你一個state url 就是一個模塊 ,要合理的使用模塊間參數。
日期格式 跟後臺的 交互,說到底不論get post 提交到後臺的始終是字符串。
JavaScript使用Date.toJSON()就可以了 後臺接收json數據 可以天然的接收 2018-05-20 18:30 這種的日期格式。
直接後臺收到的C#數據就是datetime , 轉換都不需要, get post一樣 。 但是JavaScript直接傳 new date() 到後臺則無法預知會轉換成什麽樣格式的字符串到後臺 導致c#解析DateTime類型出現錯誤。
一個頁面 並不一定只能寫那一個固定名字的controller。
還有我當爸爸了。。。
angularjs和ajax的結合使用 (三)