成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用AngularJS構(gòu)建應(yīng)用時(shí)遇到的問題及解決方案(版本為1.3.9)

cuieney / 2474人閱讀

摘要:最近在公司使用用完成了一個(gè)項(xiàng)目,在此記錄一下過程中遇到的問題及解決方案。其他兩種方法可參考站內(nèi)文章控制器如何通信結(jié)語以上為我在編寫一個(gè)應(yīng)用時(shí)遇到的問題及解決方案,記錄并分享出來,歡迎大家指正

最近在公司使用用AngularJS(1.3.9)完成了一個(gè)項(xiàng)目,在此記錄一下過程中遇到的問題及解決方案。

使用$http服務(wù)發(fā)送ajax請(qǐng)求時(shí)后端無法判斷請(qǐng)求是XMLHttpRequest

問題及場(chǎng)景
有時(shí)候后端會(huì)讀取請(qǐng)求中headerX-Requested-With字段判斷前端的請(qǐng)求是否為異步請(qǐng)求XMLHttpRequest,在使用$http服務(wù)發(fā)送請(qǐng)求時(shí)后端卻判斷為false。

原因
"X-Requested-With" : "XMLHttpRequest"并不屬于標(biāo)準(zhǔn)的header內(nèi)容,因此Angular不會(huì)在header中默認(rèn)設(shè)置該字段。

解決方案
手動(dòng)在$httpProvider中設(shè)置該字段,代碼如下:

    $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";

note:
可以創(chuàng)建一個(gè)公用服務(wù),在配置方法做這個(gè)修改,公用服務(wù)注入到每個(gè)module里就一勞永逸了。

使用$http.post()方法參數(shù)類型不正確

問題及場(chǎng)景
在angular中,使用$http.post()方法提交數(shù)據(jù)時(shí),發(fā)現(xiàn)所帶參數(shù)并非Form Data,而是JSON對(duì)象,導(dǎo)致服務(wù)器無法使用一般方法正確獲取參數(shù),而使用jQuery的$.post()方法卻可以正確獲取。

原因
兩者的post對(duì)header的處理有所不同,jQuery會(huì)把作為JSON對(duì)象的myData序列化,例如:

    var myData = { a : 1, b : 2 };
    // jQuery在post數(shù)據(jù)之前會(huì)把myData轉(zhuǎn)換成字符串:"a=1&b=2"

angular顯然沒做這個(gè)處理。

解決方案
修改Angular的$httpProvider的默認(rèn)處理,代碼如下:

    $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:
同樣應(yīng)該在公用服務(wù)中做此修改。

調(diào)用$scope.$apply(fn)更新視圖時(shí)報(bào)錯(cuò)$rootScope:inprog

問題及場(chǎng)景
在更新$scope上的model數(shù)據(jù)時(shí),如果是在digest監(jiān)聽外,會(huì)發(fā)現(xiàn)視圖并沒有自動(dòng)更新,于是手動(dòng)調(diào)用$scope.$apply(fn)方法通知視圖進(jìn)行更新,卻發(fā)現(xiàn)有時(shí)候會(huì)報(bào)錯(cuò)$rootScope:inprog。

原因
該錯(cuò)誤原因是在進(jìn)程當(dāng)中$scope.$apply(fn)正在執(zhí)行,不能在此基礎(chǔ)上重復(fù)調(diào)用該方法。

解決方案
可以在調(diào)用該方法時(shí)做一個(gè)安全檢測(cè),封裝代碼如下:

    $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中的一個(gè)內(nèi)部屬性,如果為null或者undefined則說明進(jìn)程中沒有$apply方法在運(yùn)行,則可以直接調(diào)用,否則直接執(zhí)行入?yún)⒎椒ā?/p> 添加統(tǒng)一攔截器對(duì)ajax的請(qǐng)求或返回做處理

問題及場(chǎng)景
我遇到的場(chǎng)景是在發(fā)送異步請(qǐng)求時(shí),后端會(huì)先判斷用戶是否已經(jīng)登錄,如果未登錄則會(huì)在responseheader中添加一個(gè)redirecturl字段,前端讀取該字段控制頁面跳轉(zhuǎn)到該url,我首先想到的解決方案就是前端需要做一個(gè)統(tǒng)一攔截器,對(duì)所有異步請(qǐng)求的response進(jìn)行攔截。

解決方案
通過看Angular中$httpProvider部分的源碼注釋,發(fā)現(xiàn)了攔截器的幾種寫法,我選擇的寫法源碼注釋如下:

    *   // 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的攔截器中,同樣應(yīng)該寫在公用服務(wù)的配置方法當(dāng)中。

controller之間的通信問題

問題及場(chǎng)景
當(dāng)有兩個(gè)視圖分別由兩個(gè)controller控制時(shí),其中一個(gè)視圖發(fā)生變化,需通知另一個(gè)視圖產(chǎn)生了此變化。

解決方案
總的來說,Angular中控制器通信有三種處理方法:

利用作用域繼承的方式 即子控制器繼承父控制器中的內(nèi)容;

基于事件的方式 即$on,$emit,$boardcast這三種方法;

服務(wù)方式 寫一個(gè)服務(wù)的單例然后通過注入來使用。

我選擇了最后一種方法,示例代碼如下:

    //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;
        };
    });
    //html
    
click me
my name

note:
在Angular中服務(wù)是一個(gè)單例,所以在服務(wù)中生成一個(gè)對(duì)象,該對(duì)象就可以利用依賴注入的方式在所有的控制器中共享。
如果不是通過點(diǎn)擊產(chǎn)生變化,還可結(jié)合$scope.$watch()方法來進(jìn)行通信。
其他兩種方法可參考站內(nèi)文章:AngularJS控制器controller如何通信?

結(jié)語

以上為我在編寫一個(gè)angular應(yīng)用時(shí)遇到的問題及解決方案,記錄并分享出來,歡迎大家指正!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/78509.html

相關(guān)文章

  • angular - 收藏集 - 掘金

    摘要:如何在中使用動(dòng)畫前端掘金本文講一下中動(dòng)畫應(yīng)用的部分。與的快速入門指南推薦前端掘金是非常棒的框架,能夠創(chuàng)建功能強(qiáng)大,動(dòng)態(tài)功能的。自發(fā)布以來,已經(jīng)廣泛應(yīng)用于開發(fā)中。 如何在 Angular 中使用動(dòng)畫 - 前端 - 掘金本文講一下Angular中動(dòng)畫應(yīng)用的部分。 首先,Angular本生不提供動(dòng)畫機(jī)制,需要在項(xiàng)目中加入Angular插件模塊ngAnimate才能完成Angular的動(dòng)畫機(jī)制...

    AlexTuan 評(píng)論0 收藏0
  • MEAN.js 文檔

    摘要:感謝使用框架本文檔涵蓋構(gòu)建應(yīng)用所需的基礎(chǔ)知識(shí)。用于數(shù)據(jù)校驗(yàn)的組件及相關(guān)文件在此目錄進(jìn)行管理。除了自定義中間件外,還是用了諸多第三方的中間件,它們是五測(cè)試我們使用組件對(duì)服務(wù)端代碼進(jìn)行測(cè)試。識(shí)別當(dāng)前導(dǎo)航從已有導(dǎo)航中刪除給定標(biāo)識(shí)的導(dǎo)航配置。 本文同步至個(gè)人博客 MEAN.js 文檔,轉(zhuǎn)載請(qǐng)注明出處。 Overview 感謝使用 MEAN.js 框架! 本文檔涵蓋構(gòu)建 MEAN 應(yīng)用所需的基礎(chǔ)...

    Hydrogen 評(píng)論0 收藏0
  • 可能是你見過最完善微前端解決方案

    摘要:而從技術(shù)實(shí)現(xiàn)角度,微前端架構(gòu)解決方案大概分為兩類場(chǎng)景單實(shí)例即同一時(shí)刻,只有一個(gè)子應(yīng)用被展示,子應(yīng)用具備一個(gè)完整的應(yīng)用生命周期。為了解決產(chǎn)品研發(fā)之間各種耦合的問題,大部分企業(yè)也都會(huì)有自己的解決方案。 原文鏈接:https://zhuanlan.zhihu.com/p/... Techniques, strategies and recipes for building a modern ...

    Kahn 評(píng)論0 收藏0
  • 前端練級(jí)攻略(第二部分)

    摘要:是文檔的一種表示結(jié)構(gòu)。這些任務(wù)大部分都是基于它。這個(gè)實(shí)踐的重點(diǎn)是把你在前端練級(jí)攻略第部分中學(xué)到的一些東西和結(jié)合起來。一旦你進(jìn)入框架部分,你將更好地理解并使用它們。到目前為止,你一直在使用進(jìn)行操作。它是在前端系統(tǒng)像今天這樣復(fù)雜之前編寫的。 本文是 前端練級(jí)攻略 第二部分,第一部分請(qǐng)看下面: 前端練級(jí)攻略(第一部分) 在第二部分,我們將重點(diǎn)學(xué)習(xí) JavaScript 作為一種獨(dú)立的語言,如...

    BWrong 評(píng)論0 收藏0
  • 2017年前端流行數(shù)百個(gè)javascript庫(kù),你會(huì)幾個(gè)?

    摘要:有數(shù)百個(gè)免費(fèi)的庫(kù)出來,為應(yīng)用程序選擇正確的框架變得非常困難。是流行的驅(qū)動(dòng)技術(shù)之一,由于年創(chuàng)建。在這三個(gè)塊中,有幾個(gè)暴露低層接口的綁定。反應(yīng)由,和許多開發(fā)人員和個(gè)人的社區(qū)維護(hù)。誕生于年,是一個(gè)輕量級(jí)的框架。 有數(shù)百個(gè)免費(fèi)的JS庫(kù)出來,為應(yīng)用程序選擇正確的JavaScript框架變得非常困難。一些開發(fā)商最終會(huì)拋棄,而其他開發(fā)者則迅速發(fā)展,并得到廣泛采用。許多開發(fā)人員只知道像jQuery和R...

    CoXie 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<