iT邦幫忙

DAY 15
1

我在前端 ng 時系列 第 15

初談 directive

directive 在 AngularJS 的開發中扮演了非常重要的角色。
使用 directive 指令可在指定的 DOM 元素標記,讓該元素有特定的行為或是轉換該元素的 DOM。

在實作 AngularJS application 的過程,我們一定會使用到 AngularJS 內建提供的 directive。

比方說,

  • 實作 two-way data bindings (ng-model)
  • 操作 HTML DOM (ng-class , ng-show, ng-if)
  • 綁定事件,跟使用者互動 (ng-click, ng-change)
  • 產生 templates (ng-repeat, ng-switch)

基本上,AngularJS 已提供了很多平常做網站需要的 directive。
可是,當內建 directive 不能完成我們的需求,建立客製化 directive 還是需要的。

我每次在解決寫 directive 遇到的問題時,總是會發現 directvie 新用法或屬性。
寫久後覺得瞭解 directive 的各屬性是很有用的,所以接下來幾篇來介紹 directive 屬性吧~

1. directive 名稱:
AngularJS 正規化 directive 名稱在宣告時是寫駝峰寫法 (camelCase)。ex: myNiceDirective
可是因為在 HTML 是沒有區分大小寫的 (case-insensitive) ,所以在 HTML 中宣告是需改成破折號 (-)。ex: my-nice-directive

規則如下:

  1. 可在 element/attributes 前面可加 x- 跟 data- 。
    ( ex: data-my-nice-directive 等於使用 myNiceDirective )
  2. 當遇到 : 、 - 或 _ 會自動劃分成駝峰寫法。
    (ex: ng:model、ng-model 、ng_model 都是要使用 ngModel)

2. priority (default: 0)
一個 element 可同時擁有多個 directives,並且可設定 priority 來排列 directives compile 順序。
priority 的數字越大的會越先 compile。

ex:
ng-repeat: 1000
ng-href: 99
ng-click: 0
compile 順序就是 ng-repeat -> ng-href -> hg-click

3. restrict (default: A)
此 directive 的宣告方式

  • E: Element name

  • A: Attribute

  • C: Class (儘量不要用)

  • M: Comment (絕對不要用)

directive 到底要用 Element 還是 Attribute?

我的分法很簡單,
假如該 directive 性質是像是 component ,性質是獨立的,我會用 Element。ex: map
假如該 directive 性質像是 plugin,會幫綁定的 DOM 元素加行為,我會用 Attribute。ex: ng-click

當然... 假如需要支援 IE8-,我一概都用 Attribute。(IE8- 不支援 custom element tag)
官網使用前 IE 規範

4.1 template (default: template 內容會取代元素的內容)
變更綁定元素的 HTML:

  • template 內容會取代元素的內容
  • template 內容會取代元素本身 (假如 replace 是 true)
  • template 內容會包圍元素的內容 (假如 transclude 是 true)

4.2 templateUrl
跟 template 功能一樣,只是差別是 templateUrl 是載入外部的 template。
官網範例

template 跟 templateUrl 兩者都可用 function 格式,只要 return string value 就好。
範例:http://plnkr.co/edit/5YKO3R1chIRNL1sGEAwx

  angular.module('myExample', [])
    .controller('myCtrl', ['$scope', function($scope) {
      $scope.myName = 'luffy';
    }])
    .directive('myDirective', function() {
      return {
        templateUrl: function (elem, attrs) {
          // 一定要 return string
          return attrs['has-name'] === 'my' ? 'myTmpl.html' : 'yourTmpl.html';
        }
      };
    });

5. replace (default: false)

  • template 內容會取代元素本身

  • 當 replace 是 true 的時候,template 本身的 root node 只能有一個。

    get error
    

正確:

<div>
    my name is {{myName}}
    <span> it's ok! </span>
</div>
  • 預計在 AngularJS v2.0 此屬性會被移除。
    原因官方說是因為他們除了 SVG element 外,沒有需要 replace 元素本身的必要。官方說法

下集待續!


上一篇
ui-router - 監聽事件
下一篇
初談 directive - scope
系列文
我在前端 ng 時30

1 則留言

0
Andy Chiu
iT邦研究生 3 級 ‧ 2015-09-24 21:24:08

請教一下,4.2 templateUrl裡面的範例,要怎樣改變,才會使用'yourTmpl.html'這個template呢?

我要留言

立即登入留言