一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。
前言
实战
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 = ; i < ; i++)
{
TaskDetails newTask = new TaskDetails
{
Id = i,
Title = "Task " + (i + ),
Details = "Task Details " + (i + ),
Starts = DateTime.Now,
Ends = DateTime.Now.AddDays(i + )
};
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 = ; 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 。的更多相关文章
- ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript 。
一个简单的 ASP.NET MVC 例子演示如何在 Knockout JS 的配合下,使用 TypeScript . 前言 TypeScript 是一种由微软开发的自由和开源的编程语言.它是JavaS ...
- 一个简单的ASP.NET MVC异常处理模块
一.前言 异常处理是每个系统必不可少的一个重要部分,它可以让我们的程序在发生错误时友好地提示.记录错误信息,更重要的是不破坏正常的数据和影响系统运行.异常处理应该是一个横切点,所谓横切点就是各个部分都 ...
- ASP.NET MVC验证码演示(Ver2)
前一版本<ASP.NET MVC验证码演示>http://www.cnblogs.com/insus/p/3622116.html,Insus.NET还是使用了Generic handle ...
- 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数
[问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...
- 在ASP.Net MVC 中,如何在Global.asax中配置一个指向Area内部的默认Route
ASP.Net MVC 中配置Route的时候可以设置一个默认的Route. 比如我要在输入http://localhost的时候默认进入http://localhost/home/index.可以在 ...
- 开始一个简单的ASP.NET Web API 2 (C#)
创建一个Web API 项目 在本教程中,你将使用ASP.NET Web API 来创建一个web API 并返回产品列表. 网页前端使用jQuery 显示结果. 选择ASP.NET Web Appl ...
- 从一个简单的ASP.NET 5站点开启.NET跨平台之旅
在经历了阿里云上“黑色1秒”的空欢喜之后,我们“被迫”考虑实现.NET的跨平台,将Web服务器由Windows换成Linux.而这种“被迫”在一个存在已久的愿望下,变得水到渠成.这个愿望就是 —— “ ...
- ASP.NET MVC验证码演示
我们在网站登录或理一个评论时,可以放置一个验证码(Captcha),可以为系统免去那些恶意刷新等功能. 今次Insus.NET在asp.net mvc应用程序实现与演示验证码的产生以及应用等 . 前天 ...
- 简单的ASP.NET MVC发布
学习这样久的ASP.NET MVC,但一直没有实现过发布MVC程序.今天来试试. 分两个部分进行,先是第一部分,Visual Studio的publish:创建一个带有实例的ASP.NET MVC: ...
随机推荐
- 理解与模拟一个简单servlet容器
servlet接口 使用servlet编程需要实现或者继承实现了javax.servlet.Servlet接口的类,其中定义了5个签名方法: public void init(ServletConfi ...
- [转] java.lang.IllegalArgumentException: Document base D:\apache-tomcat-7.0.47\webapps\XXX错误
启动服务器,报上述错误,是因为在服务器中(如tomcat)删除了某项目,单残留的配置文件没删除造成的.解决办法是到服务器中找到conf\Catalina\localhost下找到错误信息中对应的配置文 ...
- DataWindow.Net 2.5 配置
在用过的所有的开发工具中,感觉最简单好用的就数PB了,他的DataWindow最方便,拖拖拽拽就把报表做好了,可惜现在很少人有用了.现在C/S系统一般用C#来做,但是做报表的时候总感觉没有DataWi ...
- python数据持久存储:pickle模块的使用
python的pickle模块实现了基本的数据序列和反序列化.通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储:通过pickle模块的反序列化操作,我们能够从文件 ...
- Mac 安装 home Brew以及 XCTool的过程记录
一.HomeBrew相关: 先对HomeBrew做一个简单的介绍吧,之前了解的也不多. 主要就是用于安装Unix的工具包. 注意:HomeBrew依赖于Xcode的 Command Line Tool ...
- 基本语法 protocols Category extension
转:http://blog.csdn.net/wangeen/article/details/16989529 protocol 本质就是一系列的method的声明,他并不像class是必须的选项 ...
- 【转】升级Xcode6.3插件失效解决办法
1.打开终端,输入以下代码获取到DVTPlugInCompatibilityUUID defaults read /Applications/Xcode.app/Contents/I ...
- 管理windows防火墙
1.导出防火墙规则 netsh advfirewall export "c:\advfirewall.wfw" 2.禁用防火墙 netsh firewall set opmode ...
- http协议读书笔记2-连接管理
一.http是如何使用tcp连接的? http连接本质就是tcp连接和一些使用连接的规则.所有的http通讯都是由tcp/ip来承载的.tcp/ip是全球计算机及网络设备都在使用的一种常用的分组交换的 ...
- IOS开发 应用程序图标数字角标
其实实现这个功能很简单,只要调用UIApplication即可. 用法用例:[UIApplication sharedApplication].applicationIconBadgeNumber ...