AngularJS 筆記

AngularJS 筆記

使用angularjs已經有一年多的時間,在這期間遇到過很多的問題,但卻都沒有記錄下來,以致於不少時候都得反覆去查找相同的資料,因此如今打算今後刻開始積累記錄。html

fromJson 和 toJson 方法

angular.fromJson()方法是把json轉化爲對象或者對象數組,源碼以下:jquery

function fromJson(json) {
        return isString(json) ? JSON.parse(json) : json  
    }

angular.toJson()方法是把對象或者數組轉化json,源碼以下:git

function toJson(obj, pretty) {
        return "undefined" == typeof obj ? undefined : JSON.stringify(obj, toJsonReplacer, pretty ? "  " : null)  
    }

promise

angular的promise是由$q提供和構件的,$q提供了一個經過註冊一個promise項目來異步執行的方法。angularjs

JS中處理異步回調老是很是麻煩,複雜:github

// 案例1:在前一個動畫執行完成後,緊接着執行下一個動畫
$('xx').animate({xxxx}, function(){
    $('xx').animate({xx},function(){
        //do something
    },1000)
},1000)
// 案例2:jquery ajax 異步請求
$.get('url').then(function () {
    $.post('url1').then(function () {
      //do something
    });
});

Promise 有助於開發人員逃離深度嵌套異步回調函數的深淵。Angularjs他經過$q服務提供和構建promise。一個最完整的案例:ajax

var defer1 = $q.defer();

   function fun() {
       var deferred = $q.defer();
       $timeout(function () {
           deferred.notify("notify");
           if (iWantResolve) {
               deferred.resolve("resolved");
           } else {
               deferred.reject("reject");
           }
       }, 500);
       return deferred.promise;
   }

   $q.when(fun())
       .then(function(success){
           console.log("success");
           console.log(success);
       },function(err){
           console.log("error");
           console.log(err);
       },function(notify){
           console.log("notify");
           console.log(notify);
       })
       .catch(function(reson){
           console.log("catch");
           console.log(reson);
       })
       .finally(function(final){
           console.log('finally');
           console.log(final);
       });

Promise的調用:$q.when(fun()).then(successCallback, errorCallback, notifyCallback); 簡寫爲:fun().then(successCallback, errorCallback, notifyCallback); json

angularjs service封裝使用:api

angular.module("MyService", [])
.factory('githubService', ["$q", "$http", function($q, $http){
    var getPullRequests = function(){
    var deferred = $q.defer();
    var promise = deferred.promise;
    $http.get("url")
    .success(function(data){
        var result = [];
        for(var i = 0; i < data.length; i++){
            result.push(data[i].user);
            deferred.notify(data[i].user); // 執行狀態改變通知
        }
        deferred.resolve(result); // 成功解決(resolve)了其派生的promise。參數value未來會被用做successCallback(success){}函數的參數value。
        })
    .error(function(error){
        deferred.reject(error); // 未成功解決其派生的promise。參數reason被用來講明未成功的緣由。此時deferred實例的promise對象將會捕獲一個任務未成功執行的錯誤,promise.catch(errorCallback(reason){...})。
    });
    return promise;
}

return {
    getPullRequests: getPullRequests
};
}]);

angular.module("MyController", [])
    .controller("IndexController", ["$scope", "githubService",                                function($scope, githubService){
        $scope.name = "dreamapple";
        $scope.show = true;
        githubService.getPullRequests().then(function(result){
            $scope.data = result;
        },function(error){
        },function(progress){
           // 執行狀態通知 notifyCallback
        });
    }]);

$http、$httpProvider服務

https://docs.angularjs.org/ap...$http
https://www.cnblogs.com/keatk...

$http 是angular 封裝好的 XMLHttpRequest 請求,angular 的思想偏向restful概念, 方法有:GET,POST,PUT,DELTE,PATCH,HEAD等數組

angular 默認的請求頭:
Accept: application/json, text/plain 接受json和text
Content-Type : application/json
若是要修改默認設置的話能夠在app.config上作修改promise

var app = angular.module("app", []);
app.config(function ($httpProvider) {           
    log(angular.toJson($httpProvider.defaults));
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
    $httpProvider.defaults.headers.put["Content-Type"] = "application/x-www-form-urlencoded";
    $httpProvider.defaults.headers.patch["Content-Type"] = "application/x-www-form-urlencoded";
});

只要是default的headers,在每次發送請求的時候都會帶上。因此若是咱們每一個請求都有用到一些自定義的header,咱們也能夠寫入在default.headers中。$httpProvider.defaults.headers.common["myHeader"] = "myheaderValue";//common 表示無論任何的 method POST,GET,PUT等

這些default的header是能夠在每一次咱們發請求的時候經過參數來覆蓋掉.另外$http service 也提供了一個defaults的指針 (注: $httpProvider.defaults === $http.defaults )

$httpProvider.defaults.transformRequest & transformResponse

這是angular提供給咱們的2個接口,在請求發送前和響應尚未觸發callback前對post data 和 response data作一些處理它們是個數組類型,咱們能夠push一些函數進去 (angular默認對request和response都放入了一個方法,post的時候若是data是對象將json化,響應時若是data是json類型,將解析成對象)。在每一次的請求,咱們依然能夠覆蓋整個數組。

var app = angular.module("app", []);
app.config(function ($httpProvider) {            
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
    $httpProvider.defaults.transformRequest.shift(); //把angular default的去掉
    $httpProvider.defaults.transformRequest.push(function (postData) { //這個function不是依賴注入哦
        if (angular.isObject(postData)) { 
            return $.param(postData); //若是postData是對象就把它轉成param string 返回, 這裏借用了jQuery方法
        }
        return postData;
    });
    $httpProvider.defaults.transformResponse.push(function (responseData) {
        log(angular.toJson(responseData)); //響應的數據能夠作一些處理
        return "data";
    });
});
app.controller("ctrl", function ($scope, $http) {
    $http({
        method: "POST",
        url: "handle.ashx",
        data: {
            key: "value"
        },
        transformResponse: [], //每一次請求也能夠覆蓋default
        transformResponse: $http.defaults.transformResponse.concat([function () { return "abc" }]) //若是default要保留要concat
    }).success(function (responseData) {
        log(responseData === "abc"); //true
    });
});

$httpProvider.defaults.cache。angular 默認cahce = false, 同樣能夠經過defaults去設置每一個請求。咱們也能夠在每次請求覆蓋設置。當同時發送2個沒有緩存的請求時,angular也能處理,只發送一次。

var app = angular.module("app", []);
app.config(function ($httpProvider) {
    $httpProvider.defaults.cache = true;          
});
app.controller("ctrl", function ($scope, $http) {
    //併發可是隻會發送一個請求
    $http.get("handle.ashx");
    $http.get("handle.ashx");
     
    //咱們能夠爲每次請求要不要使用緩存或者緩存數據
    $http({
        url: "handle.ashx",
        method: "GET",
        cahce: true
    });
    $http({
        url: "handle.ashx", 
        method: "GET",
        cache : false //強制不使用緩存,即便已存在
    });
});

$httpProvider.interceptors
(interceptors 中文是攔截的意思)。除了以前介紹過的 transform 能夠對數據作一些處理, angular也提供了另外4個時刻,分別是 onRequest, onRequestFail, onResponse, onResponseFail。讓咱們作一些而外處理. 好比當咱們server返回500的時候,可能咱們想作一個通用的alert,或是request fail 的話自動調整一下config在嘗試請求等等.

//interceptors是數組,放入的是能夠依賴注入的方法哦!
    $httpProvider.interceptors.push(["$q", function ($q) {
        return {
            request: function (config) { //config = {method, postData, url, headers} 等                            
                return config; //返回一個新的config,能夠作一些統一的驗證或者調整等.
            },
            requestError: function (rejection) {                      
                return $q.reject(rejection); //必須返回一個promise對象                                              
            },
            response: function (response) {                     
                return response; //這裏也能夠返回 promise, 甚至是把它給 $q.reject掉
            },
            responseError: function (rejection) { //rejection = { config, data, status, statusText, headers }                
                return $q.reject(rejection); //必須返回一個promise對象                  
            }
        };
    }]);

transform 的執行次序是這樣的 interceptors.request -> transformRequest -> transformResponse -> interceptors.response


判斷視圖是否渲染完成

// 指令
app.directive('eventNgRepeatDone', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last) {
                // $timeout(function () {
                    scope.$emit('eventNgRepeatDone');
                    if ($attrs.ngRepeatDone) {
                        $scope.$apply(function () {
                            $scope.$eval($attrs.ngRepeatDone);
                        });
                    }
                //});
            }
        }
    }
});

<!-- 使用 -->
<div ng-repeat = "item in list track by $index" event-ng-repeat-done>{{item.name}}</div>

app.controller('myCtrl', ['$scope', function ($scope) {
    $scope.$on ('eventNgRepeatDone', function () {
        // doSomething
    });
});
相關文章
相關標籤/搜索