摘要:最近在公司使用用完成了一個項目,在此記錄一下過程中遇到的問題及解決方案。其他兩種方法可參考站內文章控制器如何通信結語以上為我在編寫一個應用時遇到的問題及解決方案,記錄并分享出來,歡迎大家指正
最近在公司使用用AngularJS(1.3.9)完成了一個項目,在此記錄一下過程中遇到的問題及解決方案。
使用$http服務發送ajax請求時后端無法判斷請求是XMLHttpRequest問題及場景:
有時候后端會讀取請求中header的X-Requested-With字段判斷前端的請求是否為異步請求XMLHttpRequest,在使用$http服務發送請求時后端卻判斷為false。
原因:
"X-Requested-With" : "XMLHttpRequest"并不屬于標準的header內容,因此Angular不會在header中默認設置該字段。
解決方案:
手動在$httpProvider中設置該字段,代碼如下:
$httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
note:
可以創建一個公用服務,在配置方法做這個修改,公用服務注入到每個module里就一勞永逸了。
問題及場景:
在angular中,使用$http.post()方法提交數據時,發現所帶參數并非Form Data,而是JSON對象,導致服務器無法使用一般方法正確獲取參數,而使用jQuery的$.post()方法卻可以正確獲取。
原因:
兩者的post對header的處理有所不同,jQuery會把作為JSON對象的myData序列化,例如:
var myData = { a : 1, b : 2 }; // jQuery在post數據之前會把myData轉換成字符串:"a=1&b=2"
angular顯然沒做這個處理。
解決方案:
修改Angular的$httpProvider的默認處理,代碼如下:
$httpProvider.defaults.transformRequest = function(obj){ var str = []; for(var p in obj) { str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); } return str.join("&"); }; $httpProvider.defaults.headers.post = { "Content-Type": "application/x-www-form-urlencoded" };
note:
同樣應該在公用服務中做此修改。
問題及場景:
在更新$scope上的model數據時,如果是在digest監聽外,會發現視圖并沒有自動更新,于是手動調用$scope.$apply(fn)方法通知視圖進行更新,卻發現有時候會報錯$rootScope:inprog。
原因:
該錯誤原因是在進程當中$scope.$apply(fn)正在執行,不能在此基礎上重復調用該方法。
解決方案:
可以在調用該方法時做一個安全檢測,封裝代碼如下:
$scope.safeApply = function(fn) { var phase = this.$root.$$phase; if (phase === "$apply" || phase === "$digest") { if (fn && (typeof(fn) === "function")) { fn(); } } else { this.$apply(fn); } };
note:
$$phase變量是scope中的一個內部屬性,如果為null或者undefined則說明進程中沒有$apply方法在運行,則可以直接調用,否則直接執行入參方法。
問題及場景:
我遇到的場景是在發送異步請求時,后端會先判斷用戶是否已經登錄,如果未登錄則會在response的header中添加一個redirecturl字段,前端讀取該字段控制頁面跳轉到該url,我首先想到的解決方案就是前端需要做一個統一攔截器,對所有異步請求的response進行攔截。
解決方案:
通過看Angular中$httpProvider部分的源碼注釋,發現了攔截器的幾種寫法,我選擇的寫法源碼注釋如下:
* // register the interceptor as a service * $provide.factory("myHttpInterceptor", function($q, dependency1, dependency2) { * return { * // optional method * "request": function(config) { * // do something on success * return config; * }, * * // optional method * "requestError": function(rejection) { * // do something on error * if (canRecover(rejection)) { * return responseOrNewPromise * } * return $q.reject(rejection); * }, * // optional method * "response": function(response) { * // do something on success * return response; * }, * * // optional method * "responseError": function(rejection) { * // do something on error * if (canRecover(rejection)) { * return responseOrNewPromise * } * return $q.reject(rejection); * } * }; * }); * $httpProvider.interceptors.push("myHttpInterceptor");
我攔截response的代碼如下:
commonService.factory("redirectInterceptor", function(){ return { "response": function(response) { if(response.headers().redirecturl) { window.location.href = response.headers().redirecturl; } return response; } }; }); $httpProvider.interceptors.push("redirectInterceptor");
note:
最后一行表示將該攔截器登記到$httpProvider的攔截器中,同樣應該寫在公用服務的配置方法當中。
問題及場景:
當有兩個視圖分別由兩個controller控制時,其中一個視圖發生變化,需通知另一個視圖產生了此變化。
解決方案:
總的來說,Angular中控制器通信有三種處理方法:
利用作用域繼承的方式 即子控制器繼承父控制器中的內容;
基于事件的方式 即$on,$emit,$boardcast這三種方法;
服務方式 寫一個服務的單例然后通過注入來使用。
我選擇了最后一種方法,示例代碼如下:
//JS var app = angular.module("myApp", []); app.factory("instance", function(){ return {}; }); app.controller("MainCtrl", function($scope, instance) { $scope.change = function() { instance.name = $scope.test; }; }); app.controller("sideCtrl", function($scope, instance) { $scope.add = function() { $scope.name = instance.name; }; });
//htmlclick memy name
note:
在Angular中服務是一個單例,所以在服務中生成一個對象,該對象就可以利用依賴注入的方式在所有的控制器中共享。
如果不是通過點擊產生變化,還可結合$scope.$watch()方法來進行通信。
其他兩種方法可參考站內文章:AngularJS控制器controller如何通信?
以上為我在編寫一個angular應用時遇到的問題及解決方案,記錄并分享出來,歡迎大家指正!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78509.html
摘要:如何在中使用動畫前端掘金本文講一下中動畫應用的部分。與的快速入門指南推薦前端掘金是非常棒的框架,能夠創建功能強大,動態功能的。自發布以來,已經廣泛應用于開發中。 如何在 Angular 中使用動畫 - 前端 - 掘金本文講一下Angular中動畫應用的部分。 首先,Angular本生不提供動畫機制,需要在項目中加入Angular插件模塊ngAnimate才能完成Angular的動畫機制...
摘要:感謝使用框架本文檔涵蓋構建應用所需的基礎知識。用于數據校驗的組件及相關文件在此目錄進行管理。除了自定義中間件外,還是用了諸多第三方的中間件,它們是五測試我們使用組件對服務端代碼進行測試。識別當前導航從已有導航中刪除給定標識的導航配置。 本文同步至個人博客 MEAN.js 文檔,轉載請注明出處。 Overview 感謝使用 MEAN.js 框架! 本文檔涵蓋構建 MEAN 應用所需的基礎...
摘要:而從技術實現角度,微前端架構解決方案大概分為兩類場景單實例即同一時刻,只有一個子應用被展示,子應用具備一個完整的應用生命周期。為了解決產品研發之間各種耦合的問題,大部分企業也都會有自己的解決方案。 原文鏈接:https://zhuanlan.zhihu.com/p/... Techniques, strategies and recipes for building a modern ...
摘要:是文檔的一種表示結構。這些任務大部分都是基于它。這個實踐的重點是把你在前端練級攻略第部分中學到的一些東西和結合起來。一旦你進入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進行操作。它是在前端系統像今天這樣復雜之前編寫的。 本文是 前端練級攻略 第二部分,第一部分請看下面: 前端練級攻略(第一部分) 在第二部分,我們將重點學習 JavaScript 作為一種獨立的語言,如...
摘要:有數百個免費的庫出來,為應用程序選擇正確的框架變得非常困難。是流行的驅動技術之一,由于年創建。在這三個塊中,有幾個暴露低層接口的綁定。反應由,和許多開發人員和個人的社區維護。誕生于年,是一個輕量級的框架。 有數百個免費的JS庫出來,為應用程序選擇正確的JavaScript框架變得非常困難。一些開發商最終會拋棄,而其他開發者則迅速發展,并得到廣泛采用。許多開發人員只知道像jQuery和R...
閱讀 2809·2021-10-08 10:04
閱讀 3198·2021-09-10 11:20
閱讀 524·2019-08-30 10:54
閱讀 3306·2019-08-29 17:25
閱讀 2302·2019-08-29 16:24
閱讀 885·2019-08-29 12:26
閱讀 1447·2019-08-23 18:35
閱讀 1931·2019-08-23 17:53