[ASP.NET] TypeScript + AngularJs App 初始化撰寫方式

介紹使用 TypeScript + AngularJs 於 ASP.NET MVC 整合的 App 初始化撰寫方式

前言


在基本專案建置完成後,就要開始寫第一支 Angular TypeScript 了,首先設定一下 Angular 的起始程式 App.ts,不然怎麼動的起來阿XDD

恩,讓我們繼續看下去。

 

設置 Angular App


首先,我們要先將專案設定一些 Angular 要能夠使用的一些基本設定。

先開啟 View 資料夾內預設產生的 _Layout.cshtml 檔案,在你覺得順眼的地方(誤...) 加上 ng-app="ExampleApp" 名稱,等等...當然不是順眼啦!是要在 html 或 body 上面則一增加,詳情請參考 Angular 官方文件。如下

在此建議各位觀眾,一定要去裝 Web Essentials 套件,此套件對於 Html 與 Script 等等開發幫助之大,針對 angular 也有提供了智慧標籤。

 

接下來,需要設定一下 Angular 啟動程式,這部分的程式會撰寫在 App.ts 檔案裡面。

在 TypeScript 內,我們可以善用 module (命名空間) 來劃分程式的區域,先指定一個 module 名稱,一般為此應用程式的名稱

module ExampleApp {

}

在此,增加一個 Class 為 Config ,Config 主要可以做唯一些初始化設定用途,當然這邊都要使用 TypeScript 的方式寫,看起來才爽

module ExampleApp {

    /**
     * 啟動設定
     */
    export class Config {
        static $inject = ["$locationProvider", "$provide", "$compileProvider", "$httpProvider", "blockUIConfig"];

        constructor($locationProvider: ng.ILocationProvider, $provide, $compileProvider, $httpProvider, blockUIConfig) {
            // 設定 Ajax 請求攜帶 XMLHttpRequest Header
            $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
            // 設定 BlockUI
            blockUIConfig.message = "Loading...";
            blockUIConfig.autoBlock = false;
        }
    }

}
請注意!在 Config Class 內使用了靜態的 $inject 變數,是為了讓 angular 在經過 Bundle 之後,不會因為變數名稱被改變而找不到需要注入的模組,之後的 Class 也是必須用這個方式處理

從以上程式碼可以看出在 Config 的時候,你可以進行一些初始設定,例如使用了 angular block ui ,在可以在此針對 BlockUIConfigProvider 進行設定。

 

接下來我們在增加一個 Class 叫做 RegisterAngular,這是做什麼用的呢? 其用處主要在於讓我們之後撰寫的 Controller、Service、Directive 可以透過這個類別提供的方法註冊進模組中,如下。

module ExampleApp {

    /**
     * 啟動設定
     */
    export class Config {
        static $inject = ["$locationProvider", "$provide", "$compileProvider", "$httpProvider", "blockUIConfig"];

        constructor($locationProvider: ng.ILocationProvider, $provide, $compileProvider, $httpProvider, blockUIConfig) {
            // 設定 Ajax 請求攜帶 XMLHttpRequest Header
            $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
            // 設定 BlockUI
            blockUIConfig.message = "Loading...";
            blockUIConfig.autoBlock = false;
        }
    }

    /**
     * 註冊 Angular 各項服務
     */
    export class RegisterAngular {

        public static RegisterDirective(name: string, service: Array<any>): void {
            angular.module("ExampleApp.Directives").directive(name, service);
        }

        public static RegisterDirectives(object: Object): void {
            var classNames = Object.getOwnPropertyNames(object);
            classNames.forEach((className: string) => {
                this.RegisterDirective(object[className].$name, object[className].$inject);
            });
        }

        public static RegisterService(name: string, service: Function): void {
            angular.module("ExampleApp.Services").service(name, service);
        }

        public static RegisterController(name: string, service: Function): void {
            angular.module("ExampleApp.Controllers").controller(name, service);
        }

    }

}

 

最後將 Angular 的模組進行初始化,如下

module ExampleApp {

    /**
     * 啟動設定
     */
    export class Config {
        static $inject = ["$locationProvider", "$provide", "$compileProvider", "$httpProvider", "blockUIConfig"];

        constructor($locationProvider: ng.ILocationProvider, $provide, $compileProvider, $httpProvider, blockUIConfig) {
            // 設定 Ajax 請求攜帶 XMLHttpRequest Header
            $httpProvider.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
            // 設定 BlockUI
            blockUIConfig.message = "Loading...";
            blockUIConfig.autoBlock = false;
        }
    }

    /**
     * 註冊 Angular 各項服務
     */
    export class RegisterAngular {

        public static RegisterDirective(name: string, service: Array<any>): void {
            angular.module("ExampleApp.Directives").directive(name, service);
        }

        public static RegisterDirectives(object: Object): void {
            var classNames = Object.getOwnPropertyNames(object);
            classNames.forEach((className: string) => {
                this.RegisterDirective(object[className].$name, object[className].$inject);
            });
        }

        public static RegisterService(name: string, service: Function): void {
            angular.module("ExampleApp.Services").service(name, service);
        }

        public static RegisterController(name: string, service: Function): void {
            angular.module("ExampleApp.Controllers").controller(name, service);
        }

    }

    /**
    * 初始化 Angular Module
    */
    var appModules =
        [
            "ExampleApp.Directives", "ExampleApp.Controllers", "ExampleApp.Services"
        ];
    var trirdpartyModules =
        [
            "blockUI"
        ];
    appModules.forEach((module: string) => angular.module(module, []));
    appModules = appModules.concat(trirdpartyModules);
    angular.module("ExampleApp", appModules).config(Config);
    
}

在以上最後的程式碼中,將 appModules 與 thirdpartyModules 拆開了兩個陣列,主要的用意在第三方的模組有可能內部針對 angular.module 的註冊已經進行過特定處理,如果這邊統一在進行了一次 module 的註冊,可能導致第三方模組發生錯誤,所以我將自己寫的與第三方的模組進行了分開建立,最後在合併統一注入。

 

結語


經過了以上的步驟,基本的 App.ts 檔案已經完成了,當然在模組的注入與 Controller、Service 等註冊方式有很多種,你也可以直接寫成 angular.module("ExampleApp").controller(name, server) 方式,是很直覺但是並不太靈活,也歡迎提供更好的方式喔,接下來就可以進行 Controller 的撰寫。

 

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

 

 


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