其實我沒有那麼喜歡寫程式

自訂 AngularJs Directive (2): Hello World

472097903_6147a13e9d_o.jpg
延續上一篇,這一篇將詳細介紹各個選項的用法,並且會在此篇文章完成簡單的directive

定義Directive的Option說明

屬性名稱 用途
restrict 說明該directive要以何種方式宣告,像是元素、屬性、註解
priority 說明該directive和其他在同個元素的directive的優先度為何,數字越小優先度越高
template 用字串的方式編寫HTML碼,使用該directive的元素將會替換為這裡指定的HTML
templateUrl 同template,但是是指定template的url
replace 若為true則會用template取代原本的Html元素,若為false則將元素insert到元本的Html裡面
transclude 設為true可以將原本的HTML的元素內容移到template定義的HTML元素裡
scope 若給一物件則會建立一個新的scope,若指定為true則繼成自父scope
controller 為directive定義一個controller(大部分的目的是為了和其他directive互動)
require 指定該directive需要和哪些directive互動
link 可以在該方法內增加監聽事件($scope.$watch),或初始化一些資訊
compile 在link執行之前會先被執行,用於用程式動態修改template

Restrict

restrict可以讓你定義directive要用何種方式使用,你可以設為用元素、屬性、註解、class來使用你的directive
下面虛擬碼restirct的值'A'代表這個directive能用屬性的方式在view裡使用。

定義
app.directive('directiveName', function(...){
    return {
        restrict: 'A',
        ..........
    };
});

其他可用的retrict選項

E

表示用元素的方式使用directive
<directiveName></directiveName>

A

表示用屬性的方式使用directive
<div directiveName></div>

C

表示可用class的方式使用directive
<div class='directiveName'></div>

M

表示可用註解的方式使用directive
<!-- directive: directiveName -->

Priority

可以定義這個directive的優先度,若定義directive的元素上有其它的directive,將會決定的它的執行順序
數字越小代表優先度越高,返之

定義
app.directive('directiveName', function(...){
    return {
        priority: 10,
        ..........
    };
});

Template

定義directive最終要呈現在view上的HTML

定義
app.directive('directiveName', function(...){
    return {
        template: '<div>' +
                   '<div>hello</div>' +
                  '</div>'
        ..........
    };
});

TemplateUrl

同Template一樣是定義view要成現的HTML,但是是指定html檔的位置,當你的template有好幾行html要撰寫的時候,用templateUrl取代template會是個好主意...

定義
app.directive('directiveName', function(...){
    return {
        templateUrl: 'myTemplate.html',
        ..........
    };
});

ok! 目前你所學的知識已經可以開發一個簡單的directive了,讓我們來著手開發第一個directive吧

首先先定義我們的directive

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

app.directive('hello', function(){
    return {
        restrict: 'EA',
        template: '<div>hello world!</div>'
    };
});

接著開始在view使用我們定義的directive
因為我們設定restrict為'EA',代表它可使用元素和屬性的方式使用directive

view
<hello></hello>

結果你會看到網頁輸出 hello world!

很簡單不是嗎?

讓我們在為我們的directive option多加一個屬性replace

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

app.directive('hello', function(){
    return {
        restrict: 'EA',
        template: '<div>hello world!</div>',
        replace: true
    };
});

輸出的結果一樣為 hello world!,但檢查這兩個範例產生的html你會發現
第一個範例產生的html為

example1
<hello>
   <div>hello world!</div>
</hello>

第二個範例產生的html為

example2
<div>hello world!</div>

看出差別了嗎? 當replace設為true時代表會用template將元本的元素覆蓋掉,若為false(或沒指定),則直接插入至元素的內容裡。

Transclude

若我們想將元素元本的內容移到template裡面的任意位置,該如何做呢?
將transclude設為true,我們可以將元素原本的內容任意的加入到template裡
讓我們在新增一個directive,並將transclude設為true,注意到template,我們在span元素上設定一個ng-transclude的directive,意思是元素原本的內容,將會被新增到裡面。

定義
app.directive('rock', function(){
    return {
        restrict: 'EA',
        template: '<div><span ng-transclude></span> is best band in the world</div>',
        replace: true,
        transclude: true
    };
});
view
<rock>Nirvana</rock>

範例輸出的結果為Nirvana is the best band in the world

仔細觀察它所產出的html如下

html
<div>
    <span ng-transclude>
        <span ng-scope>Nirvana</span>
    </span>
    is the best band in the world
</div>

ok! 我們現在已經完成了兩支簡單的directive,但現實世界不可能這麼簡單...
這些都東西還不足以讓我們寫出有用的directive,下一篇文章將會講解link、compile、scope。