【angularJS】Directive指令

  AngularJS 經過被稱爲 指令 的新屬性來擴展 HTML。指令是擴展的 HTML 屬性,帶有前綴 ng-css

內置指令

1ng-app 指令初始化一個 AngularJS 應用程序。html

      定義了 AngularJS 應用程序的 根元素angularjs

2ng-init 指令初始化應用程序數據。api

      一般狀況下,不使用 ng-init。您將使用一個控制器或模塊來代替它。數組

3ng-model 指令把元素值(好比輸入域的值)綁定到應用程序【通常是在控制器中定義的變量】。緩存

4ng-repeat 指令會重複一個 HTML 元素:app

      對於集合中(數組中)的每一個項會 克隆一次 HTML 元素dom

      names=['Jani','Hege','Kai'] ide

<ul>
    <li ng-repeat="x in names">
      {{ x }}
    </li>
  </ul>函數

HTML DOM指令

AngularJS 爲 HTML DOM 元素的屬性提供了綁定應用數據的指令。

5ng-disabled 指令 直接綁定應用程序數據到 HTML 的 disabled 屬性,不可用

<div ng-app="" ng-init="mySwitch=true">

<p><button ng-disabled="mySwitch">點我!</button></p>

<p><input type="checkbox" ng-model="mySwitch"/>按鈕</p>

<p>

{{ mySwitch }}

</p>

ng-disabled 指令 綁定應用程序數據 "mySwitch" 到 HTML 的 disabled 屬性。

ng-model 指令 綁定 "mySwitch" 到 HTML input checkbox 元素的內(value),只能是true或者false。

6ng-show 指令隱藏或顯示一個 HTML 元素。

您可使用一個評估爲 true or false 的表達式(好比 ng-show="hour < 12")來隱藏和顯示 HTML 元素。

ng-hide 指令用於設置應用的一部分 不可見 。

ng-hide="true" 讓 HTML 元素 不可見

ng-hide="false" 讓元素可見。

7ng-click 指令定義了一個 AngularJS 單擊事件

八、ng-view指令

<div ng-view></div>

該 div 內的 HTML 內容會根據路由的變化而變化。

自定義指令

除了 AngularJS 內置的指令外,咱們還能夠建立自定義指令。

你可使用 .directive 函數來添加自定義的指令。

要調用自定義指令,HTML 元素上須要添加自定義指令名。

使用駝峯法來命名一個指令, runoobDirective, 但在使用它時須要以 - 分割, runoob-directive:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script> 
</head>
<body ng-app="myApp">
<runoob-directive></runoob-directive>
<script>
var app = angular.module("myApp", []);
app.directive("runoobDirective", function() {
    return {
        template : "<h1>自定義指令!</h1>"
    };
});
</script>
</body>
</html>
View Code

 

指令的做用究竟是什麼呢?

假如咱們有幾個控制器都須要用到相同指令可是對應不一樣事件時,此時難道須要定義不一樣的指令嗎?答案確定很顯然不是,指令說到底就是爲了【view複用】。

 當須要複用指令時,能夠經過獲取指令上屬性對應的方法,最終利用apply方法應用到對應的控制器中。

var app = angular.module('app', []);

    app.controller("first",["$scope",function($scope){
        $scope.first = function(){
            alert("第一個控制器函數");
        }
    }])

    app.controller("second",["$scope",function($scope){
        $scope.second = function(){
            alert("第二個控制器函數");
        }
    }])

    app.directive('lay', function(){
        return{
              restrict:"AE",
              link:function(scope,element,attr){
                  element.on("click",function(){
                      scope.$apply(attr.loader);  //給指令添加屬性loader
                  })
              }
        };
    });
<div ng-controller="first">
    <lay loader="first()">第一個控制器</lay>
</div>
<br/>
<div ng-controller="second">
    <lay loader="second()">第二個控制器</lay>
</div>
View Code

指令定義參數詳解

參考:http://www.javashuo.com/article/p-dqicxvgt-y.html

.directive('ngDirective', ['', function(){

        // Runs during compile

        return {

            // name: '',

            // priority: 1,

            // terminal: true,

            // scope: {}, // {} = isolate, true = child, false/undefined = no change

            // controller: function($scope, $element, $attrs, $transclude) {},

            // require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements

            // restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment

            // template: '',

            // templateUrl: '',

            // replace: true,

            // transclude: true,

            // compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, elm, attrs){}})),

            link: function($scope, iElm, iAttrs, controller) {          

            }

        };

    }]);

各屬性含義:

1、name

指令名,就是ngDirective,在html中使用時用ng-directive

注意這裏的大小寫,js中是駝峯命名。Html中全小寫。

指令名字的書寫

ngOfflineDatepicker   html中 ng-offline-datepicker

 

2、restrict

意思是替換的是什麼,【E】:元素,【A】:屬性,【C】:類名,【M】:註釋。

E:<ng-Directive></ng-Directive> 
A:<div ng-Directive></div>
C:<p class="ng-Directive"></p>
M:<!-- directive: ng-Directive  -->在註釋中的ng-Directive和後面的--之間要有間隔

3、replace:

true 時,restrict的替換才能成功

4、template

(模板)天然就不用說了。

5、tepmlateUrl

在實際開發中用template形式來給出模板彷佛不太友好,一旦替換的內容比較多那麼顯得代碼比較凌亂,此時咱們就要用到templateUrl,將模板單獨寫在一個頁面便可。這個就不用說了,在這個內容不得不說的是模板的緩存。

var app = angular.module('app', []);

    app.run(function($templateCache){

        $templateCache.put("hello.html","<h1>hello cnblogs</h1>")

    });

    app.directive("hello",function($templateCache){

        return{

            restrict:"AE",

            template:$templateCache.get("hello.html"),

            replace:true

        };

});

6、scope屬性

directive隔離Scope數據交互: https://blog.coding.net/blog/angularjs-directive-isolate-scope

directive 默認能共享 scope 中定義的屬性,例如在模版中直接使用 scope 中的對象和屬性。一般使用這種直接共享的方式能夠實現一些簡單的 directive 功能。

可是,當你要建立一個能夠重複使用的directive的時候,就不能依賴於父scope了,由於在不一樣的地方使用directive對應的父scope不同。

當你須要建立一個可重複使用的 directive,只是偶爾須要訪問或者修改父 scope 的數據,就須要使用隔離 scope。當使用隔離 scope 的時候,directive 會建立一個沒有依賴父 scope 的 scope,並提供一些訪問父 scope 的方式。

共享 scope 能夠直接共享父 scope,而隔離 scope 沒法共享父scope。

l  如何在 directive 中建立隔離 scope

因此你須要一個隔離的scope,咱們能夠向下面這樣來定義咱們的scope。

module1.directive("testDirective", function () {

        return {

            scope: {

                value: '提莫隊長正在待命!'

                         },

            template: 'Say:{{value}}'

        }

});

這樣就很方便的將咱們directive的上下文scope給定義出來了【標紅的地方】,可是,若是我想將父scope中的屬性傳遞給directive的scope怎麼辦呢?

l  隔離 scope 和父 scope 如何交互

directive 在使用隔離 scope 的時候,提供了三種方法同隔離以外的地方交互。這三種分別是 

  • @ 綁定一個局部 scope 屬性到當前 dom 節點的屬性值。結果老是一個字符串,由於 dom 屬性是字符串。【eg,綁定name:’@’,到dom節點的name=」{{name}}」】
  • & 提供一種方式執行一個表達式在父 scope 的上下文中。若是沒有指定 attr 名稱,則屬性名稱爲相同的本地名稱。
  • = 經過 directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間創建雙向綁定。

局部 scope 屬性

@ 方式局部屬性用來訪問 directive 外部環境定義的字符串值,主要是經過 directive 所在的標籤屬性({{name}})綁定外部字符串值。這種綁定是單向的,即父 scope 的綁定變化,directive 中的 scope 的屬性會同步變化,而隔離 scope 中的綁定變化,父 scope 是不知道的。

以下示例:directive 聲明未隔離 scope 類型,而且使用@綁定 name 屬性,在 directive 中使用 name 屬性綁定父 scope 中的屬性。當改變父 scope 中屬性的值的時候,directive 會同步更新值,當改變 directive 的 scope 的屬性值時,父 scope 沒法同步更新值。

js 代碼

app.controller("myController", function ($scope) {

        $scope.name = "hello world";

    }).directive("isolatedDirective", function () {

        return {

            scope: {

                name: "@"

            },

            template: 'Say:{{name}} <br>改變隔離scope的name:<input type="buttom" value="" ng-model="name" class="ng-pristine ng-valid">'

        }

})

html

<div ng-controller="myController">
<div class="result">  
       <div>父scope:
           <div>Say:{{name}}<br>改變父scope的name:<input type="text" value="" ng-model="name"/></div>
       </div>
       <div>隔離scope:
           <div isolated-directive name="{{name}}"></div>
       </div>
        <div>隔離scope(不使用{{name}}):
             <div isolated-directive name="name"></div>
         </div>
</div>  

局部 scope 屬性

= 經過 directive 的 attr 屬性的值在局部 scope 的屬性和父 scope 屬性名之間創建雙向綁定。
意思是,當你想要一個雙向綁定的屬性的時候,你可使用=來引入外部屬性。不管是改變父 scope 仍是隔離 scope 裏的屬性,父 scope 和隔離 scope 都會同時更新屬性值,由於它們是雙向綁定的關係。

局部 scope 屬性

& 方式提供一種途經是 directive 能在父 scope 的上下文中執行一個表達式。此表達式能夠是一個 function。
好比當你寫了一個 directive,當用戶點擊按鈕時,directive 想要通知 controller,controller 沒法知道 directive 中發生了什麼,也許你能夠經過使用 angular 中的 event 廣播來作到,可是必需要在 controller 中增長一個事件監聽方法。
最好的方法就是讓 directive 能夠經過一個父 scope 中的 function,當 directive 中有什麼動做須要更新到父 scope 中的時候,能夠在父 scope 上下文中執行一段代碼或者一個函數。

<div ng-controller="myController">
        <div ng-controller="myController">
            <div>
                父scope:
                <div>Say:{{value}}</div>
            </div>
            <div>
                隔離scope:
                <div isolated-directive action="click()"></div>
            </div>
        </div>
    </div>
    <script src="Scripts/angular.min.js"></script>
    <script>
        var app = angular.module("myApp", []);
        app.controller("myController", function ($scope) {
            $scope.value = "hello world";
            $scope.click = function () {
                $scope.value = Math.random();
            };
        }).directive("isolatedDirective", function () {
            return {
                scope: {
                    action: "&"
                },
                template: '<input type="button" value="在directive中執行父scope定義的方法" ng-click="action()"/>'
            }
        })
    </script>
View Code

 

7、require屬性

【指令與頁面上已定義控制器進行交互】

var app = angular.module('app', []);
    app.controller("ctrl",["$scope",function($scope){
        $scope.win = function(){
            alert("你贏了");
        }
    }])
    app.directive("lay",function(){
        return{
            restrict:"AE",
            scope:true,
            template:'<div>點擊我,有驚喜哦</div>',
            replace:true,
            link:function(scope,elment,attr){
                elment.on("click",function(){
                    scope.win();
                })
            }
        };
    });
View Code

對於頁面中已定義的控制器,指令爲與其進行交互直接經過link上的scope來獲取該控制器上的APi便可。

【指令與指令上控制器進行交互】

此時就須要用到require,此屬性的做用是指令與指令之間的交互,說的更加具體一點就是與其餘指令中控制器之間的交互。在指令中獲取其餘指令的控制器要用到link函數的第四個參數,link函數的前三個參數仍是很是容易理解,再也不敘述。那麼是怎樣在當前指令去獲取該控制器呢?這時就須要用到require屬性。

對於指令上的link與指令上的controller的什麼時候使用,咱們能夠這樣歸納:當一個指令上想向外部暴露這個指令時,此時利用controller進行暴露,而其餘指令須要利用指令時,經過屬性requirelink上的第四個參數進行獲取暴露指令的APi,不然的話咱們不須要第四個參數。

8、link和controller屬性

頁面:

<custom-directive></custom-directive>

Js:

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>xpy0928{{test}}</div>',
        link: directiveLink,
        controller:directiveController
    };

    return directive;
}

function directiveController($scope){
    $scope.test = " from contrller cnblogs";
}

function directiveLink(scope,elem,attr) {
    scope.test = scope.test + ",and from link cnblogs";
}
View Code

結論:編譯以前執行控制器(controller),編譯以後執行連接(link)。

由此咱們能夠基本得出在controller和link中應該寫什麼代碼的結論:

(1)在controller寫業務邏輯(咱們明白業務邏輯大部分是放在服務中),這裏所說的業務邏輯乃是爲呈現視圖以前而準備的數據或者是與其餘指令進行數據交互而暴露這個api。

(2)在link中主要操做DOM。用來處理dom渲染先後的一些事情,

在這個函數裏咱們能夠獲取dom結構等信息

link參數,這參數要求聲明一個函數,稱之爲連接函數。

寫法:

link: function(scope, element, attrs) {
  // 在這裏操做DOM
}

若是指令使用了require選項,那麼連接函數會有第四個參數,表明控制器或者所依賴的指令的控制器。

// require 'SomeController',
link: function(scope, element, attrs, SomeController) {
  // 在這裏操做DOM,能夠訪問required指定的控制器
}

連接函數之因此可以在指令中操做DOM,就是由於傳入的這幾個參數:scope、element、attrs

scope:即與指令元素相關聯的當前做用域,能夠用來註冊監聽器:scope.$watch()

element:即當前指令對應的元素,使用它能夠操做該元素及其子元素。例如<span my-directive></span>,這個span就是指令 my-directive所使用的元素。

attrs:由當前元素的屬性組成的對象。

 

Link中 添加CSS樣式

link: function ($scope, element) {

            $scope.winowHeight = window.screen.height; //獲取窗口高度

            element.css('height',$scope.winowHeight + 'px');

            element.css('margin-top', ($scope.winowHeight *0.3) + 'px')

        }

元素可操做的方法:

http://www.javashuo.com/article/p-pxgzlrim-z.html

相關文章
相關標籤/搜索