介紹使用 TypeScript + AngularJs 於 ASP.NET MVC 整合的 Controller 撰寫方式
前言
在萬事俱備,只欠 Controller 的情況下,終於要開始寫第一支 TypeScript 版的 Angular Controller 了,恩...但其實也跟之前的沒有差異很多,讓我們繼續看下去。
TypeScript Angular Controller
首先,我一樣先定義了一個 module 名稱為 ExampleApp.Controllers,如下
module ExampleApp.Controllers {
}
接下來一樣建立一個 Class 名為 HelloWorldCtrl,在此的命名建議是以 {檔案名稱} 加上 Ctrl,類別名稱相似檔案名稱也等於檢視名稱,你看看這是不是很直覺!
module ExampleApp.Controllers {
export class HelloWorldCtrl {
}
}
現在我們要建立一個 IHelloWorldCtrlScope 介面作為定義 angular 注入的 scope 型別,蛤? 你問我為什麼要建? 用 TypeScript 就是要用強行型別啊!不然要幹嘛!
建立介面的同時,需要 extends ng.IScope,這樣才能夠在我們定義的介面中使用到原本 angular 所提供的介面方法,如下
module ExampleApp.Controllers {
export interface IHelloWordCtrlScope extends ng.IScope {
}
export class HelloWorldCtrl {
}
}
接著,在 IHelloWordCtrlScope 增加一個 message 變數定義作為等等測試需用的變數。
而在 HelloWorldCtrl 類別中呢,先建立兩個靜態變數分別為 $name 與 $inject ,$inject 我之前提到過,是用於注入所需要的模組以及防止在 bundle 情況下注入失效,那 $name 又是作何用呢? $name 是我額外定義用來代表這個 Controller 的名稱,當我們在註冊 Angular Controller 時,需要傳入 Controller 的 name 與對應的 ControllerConstructor,像下面這樣
angular.module("ExampleApp").controller("MyCtrl", MyCtrl);
但是如果是依照上面這種寫法,如 Controller Name 有異動的時候就需要去註冊的地方更改,為了避免這種散落各地的情況,我則改在將 name 放置於相同 Class 中控管,如下
module ExampleApp.Controllers {
export interface IHelloWordCtrlScope extends ng.IScope {
message: string;
}
export class HelloWorldCtrl {
static $name = "HelloWorldCtrl";
static $inject = ["$scope"];
}
}
接下來繼續完成 constructor 的建立,透過在 constructor 傳入的 $scope 指定型別為 IHelloWorldCtrlScope 並指派 message 值,在這個撰寫過程中,你都可以使用到強行別以及 Intellisense,如下
module ExampleApp.Controllers {
export interface IHelloWordCtrlScope extends ng.IScope {
message: string;
}
export class HelloWorldCtrl {
static $name = "HelloWorldCtrl";
static $inject = ["$scope"];
private scope: IHelloWordCtrlScope;
constructor(
$scope: IHelloWordCtrlScope) {
this.scope = $scope;
this.scope.message = "Hello World!!!!";
}
}
}
最後最後,必須要將你所撰寫好的 Controller 註冊到 module 內,此時就需要呼叫在 App.ts 裡面的 RgeisterController 方法,如下
module ExampleApp.Controllers {
export interface IHelloWordCtrlScope extends ng.IScope {
message: string;
}
export class HelloWorldCtrl {
static $name = "HelloWorldCtrl";
static $inject = ["$scope"];
private scope: IHelloWordCtrlScope;
constructor(
$scope: IHelloWordCtrlScope) {
this.scope = $scope;
this.scope.message = "Hello World!!!!";
}
}
}
ExampleApp.RegisterAngular.RegisterController(
ExampleApp.Controllers.HelloWorldCtrl.$name,
ExampleApp.Controllers.HelloWorldCtrl);
在 HelloWorld 檢視頁面,增加 ng-controller 屬性,如下
<h2>HelloWorld Demo</h2>
<div ng-controller="HelloWorldCtrl">
<span ng-bind="message"></span>
</div>
執行後結果顯示如下
番外篇,加入 ViewModel 與 Event
在看完以上的基本操作後,我們可以增加更多的變化,例如在實際針對 Document 上的元素修改值時建立一個 ViewModel 處理,又或者針對 Document 上的按鈕按下時要增加對應的事件處理。
首先增加一個 HelloWorld.ViewModel.ts 檔案,內容如下
module ExampleApp.Controllers {
export class HelloWorldViewModel {
public Message: string;
}
}
接著調整一下原本的 IHelloWordCtrlScope,定義 model 使用 HelloWorldViewModel 並增加一個點擊事件,如下
module ExampleApp.Controllers {
export interface IHelloWordCtrlScope extends ng.IScope {
model: Models.HelloWorldViewModel;
SayHello(): void;
}
export class HelloWorldCtrl {
static $name = "HelloWorldCtrl";
static $inject = ["$scope"];
private scope: IHelloWordCtrlScope;
constructor(
$scope: IHelloWordCtrlScope) {
this.scope = $scope;
this.scope.SayHello = this.SayHello;
var model = new Models.HelloWorldViewModel;
model.Message = "Hello World!!!";
this.scope.model = model;
}
public SayHello(): void {
var scope: IHelloWordCtrlScope = <any>this;
scope.model.Message = "Hello Arvin!!!";
}
}
}
ExampleApp.RegisterAngular.RegisterController(
ExampleApp.Controllers.HelloWorldCtrl.$name,
ExampleApp.Controllers.HelloWorldCtrl);
HelloWorld.cshtml 檢視稍微調整如下
<h2>HelloWorld Demo</h2>
<div ng-controller="HelloWorldCtrl">
<span ng-bind="model.Message"></span><br />
<input type="button" value="Say Hello" ng-click="SayHello()" />
</div>
執行後就會產生以下結果
如果在此時在 TypeScript 是寫以下這樣
public SayHello(): void {
this.scope.model.Message = "Hello Arvin!!!";
}
就會發生操作 this.scope 是 undefined 的錯誤,所以才會額外在做這個動作將 this 直接變成 IHelloWordCtrlScope 進行操作,針對這個問題目前還未找到更佳解,希望如果有經驗的前輩可以指點一下。
結語
以上就是 Controller 的撰寫方式,感覺短短一篇結果打了好久....Orz
接下一篇 TypeScript + AngularJs Directive 撰寫方式
以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)