前言
实战
1. 定义实体类
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace TypeScriptMvc.Models { public class TaskDetails { public int Id { get; set; } public string Title { get; set; } public string Details { get; set; } public DateTime Starts { get; set; } public DateTime Ends { get; set; } } }
2. 控制器(Controller)代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using TypeScriptMvc.Models; namespace TypeScriptMvc.Controllers { public class HomeController : Controller { public ActionResult Tasks() { List<TaskDetails> tasks = new List<TaskDetails>(); for (int i = 0; i < 10; i++) { TaskDetails newTask = new TaskDetails { Id = i, Title = "Task " + (i + 1), Details = "Task Details " + (i + 1), Starts = DateTime.Now, Ends = DateTime.Now.AddDays(i + 1) }; tasks.Add(newTask); } return View(tasks); } } }
这里仅仅是循环生成了 10 条 TaskDetails 记录,并把它作为 Model 传递给 View。
3. View.cshtml 代码
@model IEnumerable<TypeScriptMvc.Models.TaskDetails> <p> @Html.ActionLink("Create New", "Create") <input type="hidden" id="serverJSON" value="@Newtonsoft.Json.JsonConvert.SerializeObject(Model)" /> </p> <table class="table"> <tr> <th> Title </th> <th> Details </th> <th> Starts </th> <th> Ends </th> <th></th> </tr> <tbody data-bind="foreach: tasks"> <tr> <td data-bind="text: title"></td> <td data-bind="text: details"></td> <td data-bind="text: starts"></td> <td data-bind="text: ends"></td> <td></td> </tr> </tbody> </table> @section Scripts{ <script src="~/Scripts/knockout-2.3.0.js"></script> <script src="~/Scripts/moment.min.js"></script> <script src="~/Scripts/typescript-list.js"></script> }
首先,我们看到 JSON 序列化了 Controller 传过来的 Model,然后用了一个 HTML Hidden 来保存。然后用 Knockout JS 的语法(请注意 <tbody> 中的 data-bind)来呈现数据,那么 Knockout JS 的数据源从哪里来呢?我们接着往下看。我们看到底部引用了一个 typescript-list.js ,进去瞧瞧。PS:typescript-list.js 这个 JS 文件并不是什么第三方 Javascript 库,完全可以把它改成 aaa.js 。另外那 2 个 JS 文件(knockout-2.3.0.js 和 moment.min.js)就是第三方库了。
4. 进入 typescript-list.js
找到 typescript-list.js 文件
///<reference path="typings/jquery/jquery.d.ts" /> ///<reference path="typings/knockout/knockout.d.ts" /> var TaskDetails = (function () { function TaskDetails(id, title, details, starts, ends) { this.id = ko.observable(id); this.title = ko.observable(title); this.details = ko.observable(details); this.starts = ko.observable(moment(starts).format("MMM DD, YYYY h:mm:ss a")); this.ends = ko.observable(moment(ends).format("MMM DD, YYYY h:mm:ss a")); } return TaskDetails; })(); var TaskViewModel = (function () { function TaskViewModel() { this.tasks = ko.observableArray([]); } return TaskViewModel; })(); $(document).ready(function () { var serverData; serverData = JSON.parse($("#serverJSON").val()); var vm; var i; vm = new TaskViewModel(); for (i = 0; i < serverData.length; i++) { var serverTask; serverTask = serverData[i]; vm.tasks.push(new TaskDetails(serverTask.Id, serverTask.Title, serverTask.Details, serverTask.Starts, serverTask.Ends)); } ko.applyBindings(vm); }); //# sourceMappingURL=typescript-list.js.map
根据 TypeScript 的背景,我猜测这个 js 文件是编译后动态生成的,语言就是 TypeScript。果然,在目录 /Scripts 下,我找到了 typescript-list.ts。 扩展名是 ts,也就是去 TypeScript 的 2 个单词的首字母。我还注意到还有一个 typescript-list.js.map 文件,我猜应该也是由 TypeScript 动态生成的,下面我们进入 typescript-list.ts 瞧瞧。
typescript-list.js.map 内容如下:
{ "version":3, "file":"typescript-list.js", "sourceRoot":"", "sources":["typescript-list.ts"], "names":["TaskDetails","TaskDetails.constructor","TaskViewModel","TaskViewModel.constructor",""], "mappings":"AAAA,kDAAkD;AAClD,sDAAsD;AAEtD;IAOIA,qBAAYA,EAAUA,EAAEA,KAAaA,EAAEA,OAAeA,EAClDA,MAAcA,EAAEA,IAAYA;QAC5BC,IAAIA,CAACA,EAAEA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,EAAEA,CAACA,CAACA;QAC5BA,IAAIA,CAACA,KAAKA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,KAAKA,CAACA,CAACA;QAClCA,IAAIA,CAACA,OAAOA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,OAAOA,CAACA,CAACA;QACtCA,IAAIA,CAACA,MAAMA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,MAAMA,CAACA,MAAMA,CAACA,CAACA,MAAMA,CAACA,yBAAyBA,CAACA,CAACA,CAACA;QAC9EA,IAAIA,CAACA,IAAIA,GAAGA,EAAEA,CAACA,UAAUA,CAACA,MAAMA,CAACA,IAAIA,CAACA,CAACA,MAAMA,CAACA,yBAAyBA,CAACA,CAACA,CAACA;IAC9EA,CAACA;IACLD;AAACA,CAAAA,IAAA;;AAED;IAEIE;QACIC,IAAIA,CAACA,KAAKA,GAAGA,EAAEA,CAACA,eAAeA,CAACA,EAAEA,CAACA,CAACA;IACxCA,CAACA;IACLD;AAACA,CAAAA,IAAA;;AAED,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;IACdE,IAAIA,UAAUA,CAAQA;IACtBA,UAAUA,GAAGA,IAAIA,CAACA,KAAKA,CAACA,CAACA,CAACA,aAAaA,CAACA,CAACA,GAAGA,CAACA,CAACA,CAACA,CAACA;IAChDA,IAAIA,EAAEA,CAAgBA;IACtBA,IAAIA,CAACA,CAASA;IACdA,EAAEA,GAAGA,IAAIA,aAAaA,CAACA,CAACA,CAACA;IACzBA,KAAKA,CAACA,GAAGA,CAACA,EAAEA,CAACA,GAAGA,UAAUA,CAACA,MAAMA,EAAEA,CAACA,EAAEA,CAAEA;QACpCA,IAAIA,UAAUA,CAAMA;QACpBA,UAAUA,GAAGA,UAAUA,CAACA,CAACA,CAACA,CAACA;QAC3BA,EAAEA,CAACA,KAAKA,CAACA,IAAIA,CAACA,IAAIA,WAAWA,CAACA,UAAUA,CAACA,EAAEA,EAAEA,UAAUA,CAACA,KAAKA,EAAEA,UAAUA,CAACA,OAAOA,EAAEA,UAAUA,CAACA,MAAMA,EAAEA,UAAUA,CAACA,IAAIA,CAACA,CAACA,CAACA;KAC3HA;IACDA,EAAEA,CAACA,aAAaA,CAACA,EAAEA,CAACA,CAACA;AACzBA,CAACA,CAAC,CAAC" }
看完,我们继续探索。
5. 进入 typescript-list.ts
找到 typescript-list.ts 文件。
///<reference path="typings/jquery/jquery.d.ts" /> ///<reference path="typings/knockout/knockout.d.ts" /> class TaskDetails { id: KnockoutObservable<number>; title: KnockoutObservable<string>; details: KnockoutObservable<string>; starts: KnockoutObservable<string>; ends: KnockoutObservable<string>; constructor(id: number, title: string, details: string, starts: string, ends: string) { this.id = ko.observable(id); this.title = ko.observable(title); this.details = ko.observable(details); this.starts = ko.observable(moment(starts).format("MMM DD, YYYY h:mm:ss a")); this.ends = ko.observable(moment(ends).format("MMM DD, YYYY h:mm:ss a")); } } class TaskViewModel { public tasks: KnockoutObservableArray<TaskDetails>; constructor() { this.tasks = ko.observableArray([]); } } $(document).ready(function () { var serverData: any[]; serverData = JSON.parse($("#serverJSON").val()); var vm: TaskViewModel; var i: number; vm = new TaskViewModel(); for (i = 0; i < serverData.length; i++) { var serverTask: any; serverTask = serverData[i]; vm.tasks.push(new TaskDetails(serverTask.Id, serverTask.Title, serverTask.Details, serverTask.Starts, serverTask.Ends)); } ko.applyBindings(vm); });
请注意这 2 行代码:
///<reference path="typings/jquery/jquery.d.ts" /> ///<reference path="typings/knockout/knockout.d.ts" />
这个可能是由 TypeScript 官方提供的组件。
可参看网址:
用近似静态语言、强类型语言的TypeScript开发属于动态语言、弱类型语言的JavaScript
代码下载:https://github.com/dotnetcurry/typescript-ko-mvc
谢谢浏览!
一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。,布布扣,bubuko.com