一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。

前言

TypeScript 是一种由微软开发的自由开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程安德斯·海尔斯伯格C#的首席架构师,已工作于TypeScript的开发。TypeScript扩展了 JavaScript 的句法,所以任何现有的JavaScript程序可以不加改变的在TypeScript下工作。TypeScript是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性。TypeScript 支持为已存在的 JavaScript 库添加类型信息的头文件,扩展了它对于流行的库如 jQueryMongoDBNode.js和 D3.js 的好处。
 
TypeScript 的官方地址:http://www.typescriptlang.org/

实战

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

谢谢浏览!

作者:音乐让我说自由的生活 - 博客园
微博:http://weibo.com/liuzuliang 
推特:https://twitter.com/liuzuliang 
脸谱:http://facebook.com/liuzuliang0813 
出处:http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。的更多相关文章

  1. 一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。

    前言 TypeScript 是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架 ...

  2. ASP.NET MVC验证码演示(Ver2)

    前一版本<ASP.NET MVC验证码演示>http://www.cnblogs.com/insus/p/3622116.html,Insus.NET还是使用了Generic handle ...

  3. 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数

    [问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...

  4. 在ASP.Net MVC 中,如何在Global.asax中配置一个指向Area内部的默认Route

    ASP.Net MVC 中配置Route的时候可以设置一个默认的Route. 比如我要在输入http://localhost的时候默认进入http://localhost/home/index.可以在 ...

  5. ASP.NET MVC验证码演示

    我们在网站登录或理一个评论时,可以放置一个验证码(Captcha),可以为系统免去那些恶意刷新等功能. 今次Insus.NET在asp.net mvc应用程序实现与演示验证码的产生以及应用等 . 前天 ...

  6. 固定Table的头部和左边的列-在Knockout Js使用场景下

    要求:固定Table的头部和左边的列 场景:Knockout Js被用于绑定Table的数据源. 固定HTML表格的头部和列是一个很常见的需求.此文:http://www.cnblogs.com/so ...

  7. 本地Debug Asp.net MVC 无法加载css与js

    运行一个从网上download的一个MVC项目,运行的时候无法显示样式,js也报错. 检查路径也没有问题,后来在配置中把其中的一段配置去掉 <staticContent> <!-- ...

  8. ASENET MVC 5 with Bootstrap and Knockout.js 第一弹

     A Basic Example Now that the Knockout library is installed, let’s get right to an example of using ...

  9. ASP.NET MVC使用Bundle来打包压缩js和css

    Bundle它是用来将js和css进行压缩(多个文件可以打包成一个文件),并且可以区分调试和非调试,在调试时不进行压缩,以原始方式显示出来,以方便查找问题. 1.BundleConfig配置Bundl ...

随机推荐

  1. Java中间MD5加密算法完整版

    携带Java软件开发过程.,因此Java中提供了自带的MessageDigest实现对文本的加密算法,以下是一个对文本进行加密的MD5加密工具类代码演示样例: package net.yuerwan. ...

  2. API接口开发 配置、实现、测试

    Yii2 基于RESTful架构的 advanced版API接口开发 配置.实现.测试 环境配置: 开启服务器伪静态 本处以apache为例,查看apache的conf目录下httpd.conf,找到 ...

  3. java_eclipse_设置全局编码_utf-8_编译class指定_运行jar乱码解决_不依赖环境

    简述: javac时指定  编码 UTF-8   [ javac -encoding UTF-8 Test.java],运行时  java 指定编码 UTF-8 这样就不会出现乱码问题[ javac ...

  4. Java经典23创意模式设计模式(两)

    本文介绍5其余两种创意模式:模型构建器(Builder).原型模型(PROTOTYPE). 一.建造者模式(别名:生成者模式) 将复杂对象的构建和它的表示分离,使得相同的构建过程能够创建不同的表示. ...

  5. ScrollView 嵌套ListView 幻灯冲突,和显示不全

    import android.content.Context; import android.util.AttributeSet; import android.widget.ListView; /* ...

  6. set RowCount 与 top n

    有时,采用top n中间n它是一个变量,这将需要使用()去完成: declare @count1 int set @count1 = 8 select top <strong>(@coun ...

  7. RPC和RMI的区别(Difference Between RPC and RMI)

    RPC和RMI的区别(Difference Between RPC and RMI) RPC vs RMI RPC (Remote Procedure Call) and RMI (Remote Me ...

  8. C#5.0新特性

    C#5.0新特性 C#5.0最大的新特性,莫过于Async和Parallel. 以往我们为了让用户界面保持相应,我们可以直接使用异步委托或是System.Threading命名空间中的成员,但Syst ...

  9. 利用webBrowser获取框架内Html页面内容

    原文:利用webBrowser获取框架内Html页面内容 利用webBrowser获取页面比较简单,MSDN下有示例,在这里不必多说. 可是一些 HTML 文档由“框架”构成,或可以存放它们自己独特 ...

  10. SQL表连接

    背景 在上次的自考科目<数据库系统原理>中.已经接触到了关于数据库表连接的一些知识,近期的学习过程中又用到了关于数据库表的连接问题,趁此再跟大家一起回想一下. 导图总结 首先用一张思维导图 ...