AngularJS之指令

来源:http://www.cnblogs.com/giggle/archive/2016/08/10/5746220.html
-Advertisement-
Play Games

初探AngularJS的指令,並對指令的常用設置項,進行闡述 ...


緊接上篇博客“初探AngularJS

一、前言

在AngularJS中指令尤為重要且內容龐多,固單獨提煉出來,梳理一番。如有錯誤,請不吝講解。

好了,言歸正傳,讓我們一起走進Angular指令的世界。

在上篇博客的前言部分提到,Angular的核心就是對HTML標簽的增強。我們用到的諸如ng-app、ng-controller等等這些都是屬於Angular指令,具體點,它們為Angular內置的指令。

Angular不僅提供了內置指令,它還允許我們自定義指令,不然Angular就太low咯。

這也是本篇博客的核心:如何自定義指令。

二、自定義指令

Angular為我們提供了.directive()這個方法,來定義指令。

如下:

正如上述代碼所示,directive方法接受兩個參數:name和factory_function。

  --name嘛,即為指令的名字,供我們調用時使用;

  --factory_function就是當我們調用指令時,指令的實際行為,並且factory_function通常返回一個對象,裡面通過規定的設置項來定義指令。

那麼自定義指令中,我們都可以操作哪些設置項呢?

如下:

var app = angular.module('myApp', []);
app.directive('myDirective', function(){
            
    return {
        restrict: 'EACM',//告訴AngularJS這個指令在DOM中以何種形式被聲明,預設為A
        priority: Number,//優先順序參數(值為數值),數值越大,優先順序越高,預設為0
        terminal: Boolean,//true或者false,告訴AngularJS是(true)否(false)停止運行當前元素上比本指令優先順序低的指令
        template: String or Template Function,//模板
        templateUrl: String,//模板URL
        replace: Boolean,//值為true,代表模板會替換掉調用該指令的元素
        scope: Boolean or Object,//指令作用域
        transclude: Boolean,//true,結合ng-transclude,在該指令中嵌入內容
        controller: String or function($scope, $element, $attrs, $transclude, otherInjectables){...},//指令控制器
        controllerAs: String,//用來設置控制器的別名
        require: String,//將控制器註入到其值所指定的指令中
        link: function(scope, element, attrs){...},
        compile: function(){}               
    };
});
代碼稍長,請自行打開

針對如此眾多的設置項,我們一同先挑幾個常用且簡單的設置項,感受感受吧。

--template & templateUrl--

template模板參數是可選的,其值可以是一段HTML文本,也可以是一個接受兩個參數的函數。

註:如果template值為空,或者沒有template設置項,那麼不會覆蓋嵌入在指令內部的元素,且當指令scope為false或者{…}時,內部元素的作用域共用外部父作用域;但,當指令scope為true時,內部元素的作用域就是繼承自外部父作用域。

demo如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myModule">
        outterDirective:<input type="text" ng-model="name"/><br>
        <one>
            innerDirective: <input type="text" ng-model="name"/>
        </one>
        <script src="angular.js"></script>
        <script>
            var myModule = angular.module('myModule', []);
            myModule.directive('one', function(){
                return {
                    scope: false,
                    restrict: 'E'
                }
            });
        </script>
    </body>
</html>
scope為false

效果圖如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myModule">
        outterDirective:<input type="text" ng-model="name"/><br>
        <one>
            innerDirective: <input type="text" ng-model="name"/>
        </one>
        <script src="angular.js"></script>
        <script>
            var myModule = angular.module('myModule', []);
            myModule.directive('one', function(){
                return {
                    scope: {},
                    restrict: 'E'
                }
            });
        </script>
    </body>
</html>
scope為{...}

scope:{...}效果同上

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myModule">
        outterDirective:<input type="text" ng-model="name"/><br>
        <one>
            innerDirective: <input type="text" ng-model="name"/>
        </one>
        <script src="angular.js"></script>
        <script>
            var myModule = angular.module('myModule', []);
            myModule.directive('one', function(){
                return {
                    scope: true,
                    restrict: 'E'
                }
            });
        </script>
    </body>
</html>
scope為true

scope為true,效果圖如下:

 

假設,設置了template後,當我們調用指令後,它會呈現在頁面中。下麵我們就來具體看看。

1、當template值為一段HTML文本時,demo如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive></div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    template: '<div>\
                                   <h1>Hi everyone!</h1>\
                               </div>'
                };
            });
        </script>
    </body>
</html>
EntireCode

2、當template值為函數時,demo如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive title="Monkey"></div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    /*
                        值為函數時,接受兩個參數tElement, tAttrs:
                            tElement:使用此指令的元素
                            tAttrs:實例的屬性,它是一個由元素上所有的屬性組成的集合,即對象
                    */
                    template: function(tElement, tAttrs){
                        var _html = '';
                        _html +='<div>' + 'Hi,'+tAttrs.title+'</div>';
                        return _html;
                    }
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

利用template可以在指令中自定義我們需要的模板,但是隨著模板的體積(代碼量)不斷變大時,在指令中利用template就顯得很糟糕,故而,使用templateUrl引用外部模板,是更好的選擇。

--restrict--

restrict 是一個可選參數,它告訴AngularJS這個指令在DOM中以何種形式被調用。一共有四個選擇且都為大寫,不然沒效果,預設為A(屬性)。

A(屬性):

<div my-directive></div>

E(元素):

<my-directive></my-directive>

C(類名):

<div class="my-directive"></div>

M(註釋):

//以註釋調用指令時,前後得有空格
<!-- directive:my-directive -->

這四個選項,可以單獨使用,亦可混合使用。如:

restrict: ‘EA’就代表可以用元素或者屬性調用指令

--replace--

replace是一個可選參數,值為Boolean類型,預設為false,代表模板會被當作子元素插入到調用此指令的元素內部。

如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive></div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    replace: false,
                    template: '<div>Monkey</div>'
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

運行後,打開chrome調試器,結果如下:

 

--replace值為true,即模板會替換掉調用指令的元素,如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive></div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    replace: true,
                    template: '<div>Monkey</div>'
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

運行後,打開chrome調試器,結果如下:

 

且,當值為true時,template會替代調用指令的元素,固template中的值,必須只包含一個根節點,不然會報錯,如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive></div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    replace: true,
                    template: '<div>Monkey</div><h1>Dorie</h1>'
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

運行後,打開chrome調試器,報錯如下:

--transclude--

transclude是一個可選參數,表示是否允許在指令中,嵌入內容。值為Boolean,預設值為false代表不允許在指令中嵌入內容,如果手動設置為true後,要結合ng-transclude指令使用,不然和false效果一樣。

下麵我們一起來編寫兩個demo具體看看。

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive>
            <span>需要嵌入內容</span>
        </div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    transclude: false,
                    template: '<div>指令內容</div>'
                };
            });
        </script>
    </body>
</html>
transclude為false

運行代碼,打開chrome調試器得下:

我們再來看看transclude:true的情況,將上述代碼中的transclude的值改為true後,運行代碼。

咦,我靠和上訴transclude:false的結果一樣呢?

哦,對了,雖然我們將transclude的值設為true了,但是要結合ng-transclude指令嘛,不然,你讓人家嵌入內容往哪插呢?

利用ng-transclude指令修改代碼後,得下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        <div my-directive>
            <span>需要嵌入內容</span>
        </div>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('myDirective', function(){
                return {
                    transclude: true,
                    template: '<div>指令內容</div><div ng-transclude></div>'
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

運行代碼,打開chrome調試器,得下:

 

註:利用ng-transclude指令標記的元素中,不管有沒有內容,都將等同於無內容情況。

咦,利用transclude嵌入的內容,它們有自己的作用域嗎?如果有,那麼它們的作用域繼承誰呢,指令or外部作用域?

答案:利用ng-transclude嵌入的內容的同時,會創建一個屬於自己的作用域,即子作用域,且繼承自外部作用域,並非指令。

--scope--

scope參數是可選的,它是直接影響指令的作用域。該參數可以被設置為不同的三個值,分別代表三種不同的作用域,下麵我們就來一一說明。

1、scope: false

當scope的值為false時,也就是預設狀態,代表指令共用父作用域,即沒有自己的作用域。

如下:

<!DOCTYPE html>
    <head>
        <meta charset="utf-8"/>
    </head>
    <body ng-app="myApp">
        Parent:<input type="text" ng-model="name"/>
        <directive-for-false></directive-for-false>
        <script src="angular.js"></script>
        <script>
            var app = angular.module('myApp', []);
            app.directive('directiveForFalse', function(){
                return {
                    restrict: 'E',
                    scope: false,
                    template: '<div>Child: \
                                  <input type="text" ng-model="name">\
                               </div>'
                };
            });
        </script>
    </body>
</html>
代碼稍長,請自行打開

執行上述代碼,效果圖如下:

 

2、scope: true

當scope的值為true時,代表指令會創建自己的作用域,且繼承自父作用域。

如下:

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 模擬登陸系統主要練習文件的操作、條件語句、迴圈等 知識點: 1.str.strip([chars]): 刪除字元串前邊和後邊的所有空格,chars參數可以定製需要刪除的字元,可選。 input().strip()可以去除用戶輸入時帶入的空格,避免產生不必要的錯誤。 用法: account = inp ...
  • # # COMMON SPRING BOOT PROPERTIES## This sample file is provided as a guideline. Do NOT copy it in its# entirety to your own application. ^^^# # # COR ...
  • # 本文對正則知識不做詳細解釋,僅作入門級的正則知識目錄。 正則表達式的強大早有耳聞,大一時參加一次選拔考試,題目就是用做個HTML解析器,正則的優勢表現得淋漓盡致。題外話不多講,直接上乾貨: 1. 元字元: 與之對應的還有反義字元,大部分為小寫字母變大寫,例如\D表示匹配非數字的字元。 2. 重覆 ...
  • 回到目錄 關於Lind.DDD.Manager的培訓與學習 講解:張占嶺 花名:倉儲大叔 主要框架:Lind.DDD,Lind.DDD.Manager 關於Lind.DDD.Manager 由於數據模型,資料庫初始化(Code.First自動升級資料庫或者進行資料庫版本的遷移)控制器,View視圖, ...
  • 在UML 2.*的13種圖形中,類圖是使用頻率最高的UML圖之一,它表示了類與類之間的關係,幫助開發人員理解系統。它是系統分析和設計階段的重要產物,也是系統編碼和測試的重要模型依據。本文詳細介紹了類間的依賴關係,關聯關係(聚合、組合等),實現關係以及繼承關係的UML表示形式及其在代碼中的實現方式。 ...
  • 1、面向過程 int a = 10; int b =5; int c = a+b; int r1 = 10; int r2 = 5; double c = r1*r1*3.14 - r2*r2*3.14 缺點:重用性差,擴展性差,可維護性差 2、面向對象 (1)對象:萬物皆對象,對象是類實例化出來的 ...
  • 迭代器的概念 迭代器是用來訪問string對象或vector對象的元素的,類似於下標運算和指針。 其對象是容器中的元素或string對象中的字元; 使用迭代器可以訪問某個元素,迭代器也能從一個元素移動到另外一個元素。 迭代器的使用 不同於指針,獲取迭代器不是使用取地址符,有迭代器的類型同時擁有返回迭 ...
  • 1.屬性選擇器 E[att]:選擇具有att屬性的E元素。 E[att="val"]:選擇具有att屬性且屬性值等於val的E元素。 E[att~="val"]:選擇具有att屬性且屬性值為一用空格分隔的字詞列表,其中一個等於val的E元素。 E[att^="val"]:選擇具有att屬性且屬性值為 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...