Stories

Detail Return Return

angularjs 學習筆記 - Stories Detail

  • 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 Leesz Avatar zaotalk Avatar inslog Avatar solvep Avatar dunizb Avatar woniuseo Avatar yuzhihui Avatar ccVue Avatar weidewei Avatar DingyLand Avatar kongsq Avatar it1042290135 Avatar
Favorites 78 users favorite the story!
Favorites

Add a new Comments

Some HTML is okay.