Stories

Detail Return Return

angularjs 學習筆記

  • angularjs官網
  • Awesome AngularJS
  • angularjs菜鳥學院
  • angular 中文網
  • angular新手經常會碰到的坑

angularjs核心功能介紹

  • 所有的東西都是綁在module上面的

    angular
        .module('app', [])  // module
        .factory()          // 工廠
        .service()          // 服務
        .controller()       // 控制器
        .directive()        // 指令
        .filter()           // 過濾器

一個angular 模塊可以包括的

angular配置階段

angular的幾個運行階段

angular 過濾器

詳細解釋

可以通過過濾器來進行各種倒敍插入等操作
  • angular自定義過濾器demo
<!DOCTYPE html>
<html lang="en">

<head>
    <title>angular自定義過濾器demo</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body ng-app="myapp" ng-controller="my">
    <ul>
        <li ng-repeat="userLayer in userLayers | reverse" ng-bind="userLayer"></li>
    </ul>
</body>
<script src="https://cdn.bootcss.com/angular.js/1.5.3/angular.min.js"></script>
<script>
    angular.module('myapp', [])
        .controller('my', function($scope, $timeout) {
            $scope.userLayers = [1, 2, 3, 4, 5, 6, 8];
        })
        .filter('reverse', function() {
            return function(items) {
                return items.slice().reverse();
            }
        })
</script>

</html>

angular 常用指令

angular所有指令大全

  • ng-app 指令初始化一個AngularJS應用程序
  • ng-init 指令初始化應用程序數據
  • ng-bind 綁定 HTML 元素到應用程序數據
  • ng-model 雙向綁定數據
ng-model 指令可以為應用數據提供狀態值(invalid, dirty, touched, error)
<form ng-app="" name="myForm" ng-init="myText = 'test@runoob.com'">
    Email:
    <input type="email" name="myAddress" ng-model="myText" required></p>
    <h1>狀態</h1>
    {{myForm.myAddress.$valid}}
    {{myForm.myAddress.$dirty}}
    {{myForm.myAddress.$touched}}
</form>
  • ng-repeatng-module 失效的時候可以使用$parent 解決,作用域的問題
  • ng-repeat for 循環遍歷數據
一些專有變量
$first 第一個
$last 最後一個
$middle 中間值
$index 索引號 從0開始
  • ng-repeat 的一些坑
如果和控制器一起寫的話,就會出現 $index 失效的問題
track by 一定要放在orderBy之後,否則會影響orderBy的效果;
當單一數組如["a","a"]有重複元素時,需要使用track by $index來保證兩個元素都會渲染,否則只會渲染一個
  • ng-repeat for 優化
<div ng-app="" ng-init="names=[
{name:'Jani',country:'Norway'},
{name:'Hege',country:'Sweden'},
{name:'Kai',country:'Denmark'}]">
<p>循環對象:</p>
<ul>
  <li ng-repeat="x in names">
    {{ x.name + ', ' + x.country }}
  </li>
</ul>
</div>
  • ng-showng-hide 顯示或隱藏 HTML 元素
  • ng-switch api
  • ng-class-odd api
  • ng-class-even 一般用於隔行換色這種功能
  • ng-class
<ANY ng-switch="expression">
  <ANY ng-switch-when="matchValue1">...</ANY>
  <ANY ng-switch-when="matchValue2">...</ANY>
  <ANY ng-switch-default>...</ANY>
</ANY>
<!--作為屬性-->
<div ng-class="key === isShow ? 'active' : ''"></div>
<!--作為css類-->
<div class="ng-class:key === isShow ? 'active' : ''"></div>
<!--另一種寫法-->
<div ng-class="{ture: 'active', false: ''}[isShow]"></div>
<!--key/value 的形式-->
<!-- 如果redStatus 和 greenStatus的值都為真, 則分別添加對應的class,適用於添加多個class -->
<div ng-class="{'red':redStatus, 'green': greenStatus}"></div>
  • ng-controller 控制器
  • ng-controller 控制器的書寫方式
//常規寫法
app.controller('wolrdCtrl', function($scope, $http){
    // ...
});

// 如果你希望對JS進行壓縮處理,那麼參數名就可能發生變化,Angular Injector將不能夠正確地注入依賴的Service。於是有另外一種寫法
app.controller('wolrdCtrl', ['$scope', '$http', function($scope, $http){
    // ...
}]);
<div ng-app="app" ng-controller='myCtrl'> {{myName}} </div>
angular.moduele('app', []).controller('myCtrl', function ($scope, $rootScope){
  $.scope.myName = '我的名字是xxxx';
  // $rootScope  可以在多個控制器中使用
})
  • ng-include

    如果是要引入外部文件的話,那麼 需要把這個路徑變成一個字符串類型的,如下
<div ng-app="">
    <div ng-include="'example.html'"></div>
</div>

angular 自定義指令

2017.7.14 試驗發現,有時候模版裏面的ng-if 不生效,解決方法是把他放到調用的地方即可,原理未知
<div ng-app="angular" ng-controller="Controller">
  <div my-customer></div>
</div>
angular.module('angular', [])
    .controller('Controller', function($scope) {
        $scope.customer = {
            name: 'Naomi',
            address: '1600 Amphitheatre'
        };
    })
    .directive('myCustomer', function() {
        return {
            restrict : 'A',
            replace : true,
            templateUrl: 'my-customer.html'
        };
});
  • directive常用設置
官網API
中文API

(1) restrict

'A' - 僅匹配屬性指令
    <!--屬性指令-->
    <div my-directive></div>
'E' - 僅匹配標籤指令
    <!--標籤指令-->
    <my-directive></my-directive>
'C' - 只匹配類名指令
    <!--類名指令-->
    <div class="my-directive"></div>
'M' - 只匹配註釋指令
    <!--註釋指令-->
    <!-- directive:my-directive -->
    <div></div>
默認是 'AE', 表示匹配屬性或標籤名, 可以根據需要進行拼接

(2) replace

true: 生成的html內容會替換掉定義此指令的html
false: 生成的html內容會插入到定義此指令的元素中
默認值是 false

(3) transclude

允許在自定義指令內繼續嵌套
在下面的例子中沒有tansclude屬性的話,hello指令下面的別的標籤就都被覆蓋了
<body>
  <hello>
    <p>asdjlkfjaksdfjlsdajf</p>
    <div>
      123131321
    </div>
    <strong>54664456</strong>
  </hello>
</body>
<script>
  angular.module('angular', []).directive('hello', function() {
    return {
      replace: true,
      transclude: true,
      template: '<h1>hellow  angular <p ng-transclude></p> </h1>',
    }
  });
  angular.bootstrap(document, ['angular']);
</script>

(4) controller 內部的控制器,可以把方法暴露到外部,給外部使用

(5) scope 獨立的作用域

讓指令有自己的作用域
    angular.module('app', []).directive('hello', function (){
        return {
            scope: {}
        }
    })

(5.1) scope 的綁定策略

scope 可以取的值:
false為默認,表示沒有獨立的作用域
true 表示有自己的獨立作用域
@ 把當前的屬性作為自字符串傳遞,還可以綁定來自外層的scope的值,在屬性之中插入{{}}即可
= 與父元素的屬性進行雙向綁定
& 傳遞一個來自父scope的函數,稍後調用
@ 和 true的區別 --

詳解


<!-- demo1 -->

(6) link 對dom進行操作 官網api 一般接收的參數

scope 控制器中的 $scope
element 將原始的DOM元素或HTML字符串包裝為jQuery元素
支持jquery的方法有
注意:請注意,此函數不會通過標籤名稱/ CSS選擇器找到元素。對於由標籤名稱查找,嘗試代替 或者,也可以使用標準的DOM API,例如。angular.element(document).find(...)$document.find()document.querySelectorAll()
attr attrs 是具有標準化屬性名稱及其對應屬性值

(6) compile 和 link 同時存在的時候,link 代碼不執行

(8) require 指令於控制器的交互

(1)require的值用?、^、或者?^修飾。
(2)如果不用任何修飾,則在當前指令中進行查找控制器。
(3)如果用^修飾,則在當前指令的父指令進行查找控制器,若未找到,則會拋出異常。
(4)如果用?修飾,則説明在當前指令中未找到控制器,此時將以null作為第四個參數。
(5)如果需要交互多個指令,則以數組形式給出,如:1
鑑於此,為了不拋出異常,我們一般以^?來進行修飾。

angular 常用服務(函數) [可以自定義服務]

在 AngularJS 中,服務是一個函數或對象,可在你的 AngularJS 應用中使用, 簡單的説,就是angular自帶的方法
  • 為啥一定要使用這些服務

    在很多服務中,比如 $location 服務,它可以使用 DOM 中存在的對象,類似 window.location 對象,但 window.location 對象在 AngularJS 應用中有一定的侷限性。
    AngularJS 會一直監控應用,處理事件變化, AngularJS 使用 $location 服務比使用 window.location 對象更好
  • $location
$location.absUrl() //獲取當前頁面的地址
  • [$http](https://docs.angularjs.org/api/ng/service/$http)
    angular中ajax請求的方法説明:
    /*
    * _http:angularJs中的$http對象
    * _url:ajax請求的URL
    * _method:請求方式:POST或GET
    * _params:GET方式請求時傳遞的參數
    * _data:POST方式請求時傳遞的參數
    * _responseType:在請求中設置XMLHttpRequestResponseType屬性,""(字符串,默認),
    * "arraybuffer"(ArrayBuffer);"blob"(blob對象);"document"(HTTP文檔)"json"(從JSON對象解析而來的JSON字符串);
    * "text"(字符串);"moz-blob"(Firefox的接收進度事件);"moz-chunked-text"(文本流);"moz-chunked-arraybuffer"(ArrayBuffer流)。
    * 這個參數表示的含義就是服務器給頁面返回的數據格式
    * _successCallback:請求成功的回調函數
    * _failureCallback:請求失敗的回調函數
    *
    */
//AngularJS1.5 以上版本的寫法
$http({
    method: 'GET',
    url: 'angular_demo.html'
}).then(function successCallback(response){
    //請求成功執行的代碼
}, function errorCallback(response){
    //請求失敗執行的代碼
});
  • [$timeout](https://docs.angularjs.org/api/ngMock/service/$timeout)
$timeout.cancel(定時器的名字);
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $timeout) {
    $scope.myHeader = "Hello World!";
    $timeout(function () {
        $scope.myHeader = "How are you today?";
    }, 2000);
});
  • AngularJS scope 原理解析
  • AngularJS事件流詳解
  • $watch api

    $watch 監聽 view層 上面的某一個對象,當他的值發生改變的時候觸發相對應的代碼
    優化: 釋放多餘的watch: stopWatch()方法
  • $apply api

    $apply把 module層 的變化傳到 view層 上面去
  • $on api

    語法 => $on(name, listener);
    用於接收 event 與 data
  • $emmit api

    語法 => $emit(name, args);
    $emit只能向parent controller傳遞event與data
  • $broadcast api

    語法 => $broadcast(name, args);
    $broadcast只能向child controller傳遞event與data
  • 阻止事件冒泡 event.stopPropagation
  • angular事件流詳解demo
<!DOCTYPE html>
<html lang="en">

<head>
    <title>angular 事件流解析</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body ng-app="app">
    <!--父級-->
    <div ng-controller="ParentCtrl">
        <!--自己-->
        <div ng-controller="SelfCtrl">
            <a ng-click="click()">點我點我點我</a>
            <!--子級-->
            <div ng-controller="ChildCtrl"></div>
        </div>
        <!--平級-->
        <div ng-controller="BroCtrl"></div>
    </div>


<br>
    <div style="color:green;">
        點擊完成之後,請在控制枱查看相關信息;
    </div>
</body>

<script src="https://cdn.bootcss.com/angular.js/1.5.3/angular.min.js"></script>
<script>
    var app = angular.module('app', []);

    app.controller('SelfCtrl', function($scope) {
        $scope.click = function() {
            // 向child controller傳遞event與data
            $scope.$broadcast('to-child', 'child');
            // 向parent controller傳遞event與data
            $scope.$emit('to-parent', 'parent');
        }
    });

    app.controller('ParentCtrl', function($scope) {
        // 用於接收event與data
        $scope.$on('to-parent', function(event, data) {
            // 父級能得到值
            console.log('我是on事件裏面的東西哦ParentCtrl', data);
        });

        $scope.$on('to-child', function(event, data) {
            // 子級得不到值
            console.log('ParentCtrl', data);
        });
    });

    app.controller('ChildCtrl', function($scope) {
        $scope.$on('to-child', function(event, data) {
            // 子級能得到值
            console.log('ChildCtrl', data);
        });
        $scope.$on('to-parent', function(event, data) {
            // 父級得不到值
            console.log('ChildCtrl', data);
        });
    });

    app.controller('BroCtrl', function($scope) {
        $scope.$on('to-parent', function(event, data) {
            // 平級得不到值
            console.log('BroCtrl', data);
        });
        $scope.$on('to-child', function(event, data) {
            // 平級得不到值
            console.log('BroCtrl', data);
        });
    });
</script>

</html>
  • [$interval](https://docs.angularjs.org/api/ng/service/$interval) 同 $timeout 的做法差不多

    取消定時器 $timeout.cancel(timeName);
  • select angular select[也可以是用ng-repeat來進行for循環]
<div ng-app="myApp" ng-controller="myCtrl">
    <select ng-init="selectedName" ng-model="selectedName" ng-options="value for (key, value) in names">
    </select>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
    $scope.names = ["Google", "Runoob", "Taobao"];
    $scope.selectdName = names[0];
});
</script>
  • tabel tabel 的相關使用

angular 常用全局方法

  • angular 所有的方法
  • angular.lowercase() 轉換字符串為小寫
  • angular.uppercase() 轉換字符串為大寫
  • angular.isString() 判斷是否是一個字符串,如果是則返回true
  • angular.isNumber() 判斷是否是一個數組,如果是則返回false
  • angular.toJson() 把數組或者對象變成字符串
  • angular.fromJson() 把字符串變成對象
  • angular.isNumber() 判斷是否是一個數組,如果是則返回false
  • angular.element($(element) || 'js原生獲取元素方法') 判斷是否是一個數組,如果是則返回false
angular.module('', []).controller('', function ($scope){
    $scope.name = 'string';
    $scope.name = angular.lowercase($scope.name); //把當前字符串轉換為小寫
})
  • angular.bootstrap 手動啓動AngularJS 程序

    官網API
    angular.bootstrap(element, [modules], [config]);
    其中第一個參數element:是綁定ng-app的dom元素;
    modules:綁定的模塊名字
    config:附加的配置
  • angular service service 裏面是不能直接注入$scope的
    //定義一個service, 按照api 的説法,service的第二個參數放的是一個構造函數,當angular 調用service的時候會自己去實例化它
    angular.module('app', []).service('getName', GetName).controller('myCtrl', function($scope, getName){
        getName.showName();//ben
    })

    function GetName (){
        this.name = "ben"
    }

    GetName.prototype.showName = fuunction (){
        console.log(this.name)
    }
  • angular factory

    //定義一個factory,
     angular.module('app', []).factory('getName', function (getName){
         var getName = {
                 showName: function () {
                     alert(1);
                 }
             }
             return getName;
     })

Service和Factory等的區別

stack_overflow的回答

angular 依賴注入

angular 路由

  • __ngRouter和ui-router__的區別

詳細攻略

  • ui-view 的三種調用方式
  • angular 使用 iframe 報錯解決方案

方案1

(1) <ui-view></ui-view>
(2) <div ui-view></div>
(3) <div class="ui-view"></div>
  • ui-router 的一些使用

    官網API
angular ui-router通過url傳值的方法:
 $scope.toDiy = function(item) {
     // 適用於 兩個項目中進行切換使用, 如果是一個項目之間切換請使用 $state.go(xx);
            window.location.href = window.location.pathname + '?item=' + item +'#/shop/classifiedList';
        }


    // ui-router帶值傳輸
    // module-config 中的配置
    $state('shop.xx', {
         url:'/classifiedList/:id/:book',
    })
    // 之後在控制器中設置
    $state.go('shop.classifiedList', {id:id, book:'xx'})
<!doctype html>
<html ng-app="myApp">
<head>
  <script src="js/angular.js"></script>
  <!-- Include the ui-router script -->
  <script src="js/angular-ui-router.min.js"></script>
  <script>
    // ...and add 'ui.router' as a dependency
    var myApp = angular.module('myApp', ['ui.router']).config(function ($stateProvider, $urlRouterProvider){
        $stateProvider
        .state('box', {
            url: '/box', // 父路由,路徑調用的形式  #/box
            templateUrl: 'example.html',
            controller: 'myCtrl', //這裏可以放一個控制器的名稱或者是一個方法
        })
        .state('box.children', {
            url: '/children',
            templateUrl: 'children.html', //子路由,路徑調用的形式  #/box/children
            controller: 'childrenCtrl'
        })
    });
  </script>
</head>
<body>
</body>
</html>
  • $cacheFactory 詳細説明
    堆棧溢出的解釋
如果您有一個請求檢索常量數據,例如城市列表。每次用户進入他必須選擇城市的表單時,從服務器獲取此列表並不是一個好的模式!所以你必須緩存這個列表。cacheFactory是為此完成的!
值的注意的是,這是應用程序的緩存服務,而不是瀏覽器本地的緩存。所以當你刷新瀏覽器,初始化整個應用程序的時候,之前的緩存數據都會丟失。那麼問題就來了,怎麼才能刷新/初始化應用程序而不丟失之前保存的數據呢,這個可以使用localStorage或者cookies
  • angular.extend
angular.extend(DST, SRC) 依次將第二個參數及後續的參數的第一層屬性(不管是簡單屬性還是對象)拷貝賦給第一個參數的第一層屬性,即如果是對象,則是引用的是同一個對象,並返回第一個參數對象
  • $q, defer, promise
    詳細解釋
    另一個版本
  • angular.fromJson

    angular.fromJson({a:'11', b:'cc'}) ==> Object {a: "11", b: "cc"}
  • angular.toJson

    angular.toJson({a:'11', b:'cc'}) ==> "{"a":"11","b":"cc"}"

angualr 入坑不完全指南

  • (1) ui.router 和 angular 一起被 require 引用的時候,會報錯
原因解析
required 原理引入機制沒有具體研究,原因就是 router 必須在 angular 框架之後引入
解決辦法
單獨先引入 angular 解決問題

  1. ?a,^?b ↩
user avatar
0 users favorite the story!

Post Comments

Some HTML is okay.