[ASP.NET] TypeScript + AngularJs Directive 撰寫方式

介紹使用 TypeScript + AngularJs 於 ASP.NET MVC 整合的 Directive 撰寫方式

前言


Controller 說完了接著就是 Directive ,Directive 也算是使用 AngularJs 時很常使用到。現在就來看看該如何透過 TypeScipt 建立 Directive 吧。

 

TypeScript AngularJs Directive


首先建立一個 Common.Directive.ts 檔案,在內容加入一個 module 名為 ExampleApp.Directives,如下

module ExampleApp.Directives {

}

 

接著想想看.... 要寫什麼樣的 Directive 進去呢? 先來做一個能夠防止表單重複點擊的 Directive 好了。

主要需求如下:

  1. 可以透過對 Submit Button 加上 Attribute Tag 即可使用
  2. 可以在表單送出的時候,將按鈕狀態變更為 Disable,並且
  3. Disable 的狀態中,可以更改按鈕文字為「請稍後...」

建立一個名為 SubmitAutoDisable 的 Class,如下

module ExampleApp.Directives {

    /** 送出自動 Disable 按鈕,可額外帶入需要顯示的文字 */
    export class SubmitAutoDisable {

    }

}

再來建立一個 $name 變數,用來存放此 Directive 的名稱,這邊要注意的是,因為 AngularJs 的 Directive 註冊時是直接返回一個 Function,所以在此宣告一個靜態方法名為 DirectiveFactory,最後在宣告一個 $inject 變數將方法指定於此陣列的最後一個位置,如果有需要 inject 其他服務,則需要放置在前面,如下

module ExampleApp.Directives {

    /** 送出自動 Disable 按鈕,可額外帶入需要顯示的文字 */
    export class SubmitAutoDisable {
        static $name = "submitAutoDisable";
        static $inject = [SubmitAutoDisable.DirectiveFactory];
        static DirectiveFactory(): ng.IDirective {
            return {

            }
        }
    }

}

完成後,就可以開始撰寫 Directive 的內容,前面有提到需求一,所以在 restrict 我們定義為 "A" 使用屬性,接著在 link 中撰寫對 Document 元素的操作,在這個範例中使用 jquery 去尋找上層的 form 表單,並在表單觸發 submit 事件的時候進行處理,如下

module ExampleApp.Directives {

    /** 送出自動 Disable 按鈕,可額外帶入需要顯示的文字 */
    export class SubmitAutoDisable {
        static $name = "submitAutoDisable";
        static $inject = [SubmitAutoDisable.DirectiveFactory];
        static DirectiveFactory(): ng.IDirective {
            return {
                restrict: "A",
                link: (scope, element, attrs) => {
                    element.parents("form").submit((event) => {

                    });
                }
            }
        }
    }

}

由於我們定義的是 A,在對應加入 Attribute 的時候可以傳入一個值進來,當然你也可以額外定義一個 Attribute 來傳入值,在此就把這個傳入的值作為當 Disable 的時候顯示的文字,這個值可以透過 attrs 中取得,而另外針對要 Disable 按鈕的操作則透過 jquery 附加一個 disabled 屬性即可,最後將這個 Directive 註冊入 Angualr 中,如下

module ExampleApp.Directives {

    /** 送出自動 Disable 按鈕,可額外帶入需要顯示的文字 */
    export class SubmitAutoDisable {
        static $name = "submitAutoDisable";
        static $inject = [SubmitAutoDisable.DirectiveFactory];
        static DirectiveFactory(): ng.IDirective {
            return {
                restrict: "A",
                link: (scope, element, attrs) => {
                    element.parents("form").submit((event) => {
                        if (attrs["submitAutoDisable"]) {
                            element.val(attrs["submitAutoDisable"]);
                        }
                        element.attr("disabled", "true");
                        element.addClass("btn-disabled");
                    });
                }
            }
        }
    }

}

ExampleApp.RegisterAngular.RegisterDirective(
    ExampleApp.Directives.SubmitAutoDisable.$name,
    ExampleApp.Directives.SubmitAutoDisable.$inject);
這邊要注意的是,在註冊 Directive 的第二個參數,是要指定為 $inject 變數。

接著在 HTML 的表單上加上 Attibute Tag,如下

<h2>HelloWorld Demo</h2>

<div ng-controller="HelloWorldCtrl">
    <span ng-bind="model.Message"></span><br />
    <input type="button" value="Say Hello" ng-click="SayHello()" />
    <br />
    <br />
    <br />
    <form action="HelloWorld" method="post">
        <input type="submit" value="送出表單" submit-auto-disable="請稍後..." />
    </form>
</div>

執行後顯示如下

 

更多的變化,使用 Block UI


相信 Block UI 各位朋友應該都有使用過,在這個範例中我們增加配合 Block UI 來防止重複點擊,順便介紹當需要 inject 其他服務時的使用方式。

首先要先載入 angular block ui 的 js 檔案與自行撰寫 Type Definition,接著需要在 App.ts 檔案裡面將 blockUI 註冊入 module 中,前置動作都完成後建立一個 SubmitAutoBlock Class 如下

/**
 *  送出自動 Block 畫面
 */
export class SubmitAutoBlock {
    static $name = "submitAutoBlock";
    static $inject = ["blockUI", SubmitAutoBlock.DirectiveFactory];
    static DirectiveFactory(blockUI: ng.IBlockUI): ng.IDirective {
        return {
            restrict: "A",
            link: (scope, element, attrs) => {
                element.parents("form").submit((event) => {
                    blockUI.start();
                });
            }
        }
    }
}

在以上程式碼中可以看到 $inject 變數中指定了注入 blockUI 服務,並且將在 DirectiveFactory 方法的 blockUI 參數中傳入,所以在 link 中即可操作 blockUI 的 start() 方法遮罩畫面。

執行後顯示如下

 

結語


以上就是 TypeScript 在撰寫 AngularJs 的基本方式,到了這裡是不是基本上已經有點概念了呢? 手癢了嗎?

 

接下一篇 TypeScript + AngularJs Service 撰寫方式

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)