public enum TaskState
{
Active = 1,
Completed =2
}
/// <summary>
/// 任务实体
/// </summary>
public class Task
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreationTime { get; set; }
public DateTime FinishTime { get; set; }
public string Owner { get; set; }
public TaskState State { get; set; }
public Task()
{
CreationTime = DateTime.Parse(DateTime.Now.ToLongDateString());
State = TaskState.Active;
}
}
/// <summary>
/// 这里仓储直接使用示例数据作为演示,真实项目中需要从数据库中动态加载
/// </summary>
public class TaskRepository
{
#region Static Filed
private static Lazy<TaskRepository> _taskRepository = new Lazy<TaskRepository>(() => new TaskRepository());
public static TaskRepository Current
{
get { return _taskRepository.Value; }
}
#endregion
#region Fields
private readonly List<Task> _tasks = new List<Task>()
{
new Task
{
Id =1,
Name = "创建一个SPA程序",
Description = "SPA(single page web application),SPA的优势就是少量带宽,平滑体验",
Owner = "Learning hard",
FinishTime = DateTime.Parse(DateTime.Now.AddDays(1).ToString(CultureInfo.InvariantCulture))
},
new Task
{
Id =2,
Name = "学习KnockoutJs",
Description = "KnockoutJs是一个MVVM类库,支持双向绑定",
Owner = "Tommy Li",
FinishTime = DateTime.Parse(DateTime.Now.AddDays(2).ToString(CultureInfo.InvariantCulture))
},
new Task
{
Id =3,
Name = "学习AngularJS",
Description = "AngularJs是MVVM框架,集MVVM和MVC与一体。",
Owner = "李志",
FinishTime = DateTime.Parse(DateTime.Now.AddDays(3).ToString(CultureInfo.InvariantCulture))
},
new Task
{
Id =4,
Name = "学习ASP.NET MVC网站",
Description = "Glimpse是一款.NET下的性能测试工具,支持asp.net 、asp.net mvc, EF等等,优势在于,不需要修改原项目任何代码,且能输出代码执行各个环节的执行时间",
Owner = "Tonny Li",
FinishTime = DateTime.Parse(DateTime.Now.AddDays(4).ToString(CultureInfo.InvariantCulture))
},
};
#endregion
#region Public Methods
public IEnumerable<Task> GetAll()
{
return _tasks;
}
public Task Get(int id)
{
return _tasks.Find(p => p.Id == id);
}
public Task Add(Task item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _tasks.Count + 1;
_tasks.Add(item);
return item;
}
public void Remove(int id)
{
_tasks.RemoveAll(p => p.Id == id);
}
public bool Update(Task item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
var taskItem = Get(item.Id);
if (taskItem == null)
{
return false;
}
_tasks.Remove(taskItem);
_tasks.Add(item);
return true;
}
#endregion
}
/// <summary>
/// Task WebAPI,提供数据服务
/// </summary>
public class TasksController : ApiController
{
private readonly TaskRepository _taskRepository = TaskRepository.Current;
public IEnumerable<Task> GetAll()
{
return _taskRepository.GetAll().OrderBy(a => a.Id);
}
public Task Get(int id)
{
var item = _taskRepository.Get(id);
if (item == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return item;
}
[Route("api/tasks/GetByState")]
public IEnumerable<Task> GetByState(string state)
{
IEnumerable<Task> results = new List<Task>();
switch (state.ToLower())
{
case "":
case "all":
results = _taskRepository.GetAll();
break;
case "active":
results = _taskRepository.GetAll().Where(t => t.State == TaskState.Active);
break;
case "completed":
results = _taskRepository.GetAll().Where(t => t.State == TaskState.Completed);
break;
}
results = results.OrderBy(t => t.Id);
return results;
}
[HttpPost]
public Task Create(Task item)
{
return _taskRepository.Add(item);
}
[HttpPut]
public void Put(Task item)
{
if (!_taskRepository.Update(item))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
public void Delete(int id)
{
_taskRepository.Remove(id);
}
}
/// <summary>
/// 只需要补充一些缺少的CSS和JS文件。因为创建模板的时候已经添加了一些CSS和JS文件
/// </summary>
public class BundleConfig
{
// For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
"~/Scripts/jquery.validate*"));
// Use the development version of Modernizr to develop with and learn from. Then, when you're
// ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
"~/Scripts/modernizr-*"));
bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
"~/Scripts/bootstrap.js",
"~/Scripts/bootstrap-datepicker.min.js"));
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/bootstrap-datepicker3.min.css",
"~/Content/site.css"));
bundles.Add(new ScriptBundle("~/bundles/knockout").Include(
"~/Scripts/knockout-{version}.js",
"~/Scripts/knockout.validation.min.js",
"~/Scripts/knockout.mapping-latest.js"));
bundles.Add(new ScriptBundle("~/bundles/app").Include(
"~/Scripts/app/app.js"));
}
}
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API 配置和服务
// Web API 路由
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// 使得序列化使用驼峰式大小写风格序列化属性
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
// 将枚举类型在序列化时序列化字符串
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> Learninghard SPA Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<p class="navbar-brand">简单任务管理系统</p>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="/">主页</a></li>
</ul>
</div>
</div>
</div>
<div class="container body-content" id="main">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - Learninghard SPA Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/knockout")
@Scripts.Render("~/bundles/app")
</body>
</html>
Index页面代码如下:
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="list" data-bind="if:canCreate">
<h2>Tasks</h2>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>编号</th>
<th>名称</th>
<th>描述</th>
<th>负责人</th>
<th>创建时间</th>
<th>完成时间</th>
<th>状态</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach:tasks">
<tr>
<td data-bind="text: id"></td>
<td><a data-bind="text: name, click: handleCreateOrUpdate"></a></td>
<td data-bind="text: description"></td>
<td data-bind="text: owner"></td>
<td data-bind="text: creationTime"></td>
<td data-bind="text: finishTime"></td>
<td data-bind="text: state"></td>
<td><a class="btn btn-xs btn-primary" data-bind="click:remove" href="javascript:void(0)">Remove</a></td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm-4">
<a href="javascript:void(0)" data-bind="click: function(data, event){ setTaskList('all') }">All </a> |
<a href="javascript:void(0)" data-bind="click: function(data, event){ setTaskList('active') }"> Active</a> |
<a href="javascript:void(0)" data-bind="click: function(data, event){ setTaskList('completed') }"> Completed</a>
</div>
<div class="col-sm-2 col-sm-offset-6">
<a href="javascript:void(0)" data-bind="click: handleCreateOrUpdate">添加任务</a>
</div>
</div>
<div id="create" style="visibility: hidden">
<h2>添加任务</h2>
<br/>
<div class="form-horizontal">
<div class="form-group">
<label for="taskName" class="col-sm-2 control-label">名称 *</label>
<div class="col-sm-10">
<input type="text" data-bind="value: name" class="form-control" id="taskName" name="taskName" placeholder="名称">
</div>
</div>
<div class="form-group">
<label for="taskDesc" class="col-sm-2 control-label">描述</label>
<div class="col-sm-10">
<textarea class="form-control" data-bind="value: description" rows="3" id="taskDesc" name="taskDesc" placeholder="描述"></textarea>
</div>
</div>
<div class="form-group">
<label for="taskOwner" class="col-sm-2 control-label">负责人 *</label>
<div class="col-sm-10">
<input class="form-control" id="taskOwner" name="taskOwner" data-bind="value: owner" placeholder="负责人">
</div>
</div>
<div class="form-group">
<label for="taskFinish" class="col-sm-2 control-label">预计完成时间 *</label>
<div class="col-sm-10">
<input class="form-control datepicker" id="taskFinish" data-bind="value: finishTime" name="taskFinish">
</div>
</div>
<div class="form-group">
<label for="taskOwner" class="col-sm-2 control-label">状态 *</label>
<div class="col-sm-10">
<select id="taskState" class="form-control" data-bind="value: state">
<option>Active</option>
<option>Completed</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button class="btn btn-primary" data-bind="click:handleSaveClick">Save</button>
<button data-bind="click: handleBackClick" class="btn btn-primary">Back</button>
</div>
</div>
</div>
</div>
var taskListViewModel = {
tasks: ko.observableArray(),
canCreate:ko.observable(true)
};
var taskModel = function () {
this.id = 0;
this.name = ko.observable();
this.description = ko.observable();
this.finishTime = ko.observable();
this.owner = ko.observable();
this.state = ko.observable();
this.fromJS = function(data) {
this.id = data.id;
this.name(data.name);
this.description(data.description);
this.finishTime(data.finishTime);
this.owner(data.owner);
this.state(data.state);
};
};
function getAllTasks() {
sendAjaxRequest("GET", function (data) {
taskListViewModel.tasks.removeAll();
for (var i = 0; i < data.length; i++) {
taskListViewModel.tasks.push(data[i]);
}
}, 'GetByState', { 'state': 'all' });
}
function setTaskList(state) {
sendAjaxRequest("GET", function(data) {
taskListViewModel.tasks.removeAll();
for (var i = 0; i < data.length; i++) {
taskListViewModel.tasks.push(data[i]);
}},'GetByState',{ 'state': state });
}
function remove(item) {
sendAjaxRequest("DELETE", function () {
getAllTasks();
}, item.id);
}
var task = new taskModel();
function handleCreateOrUpdate(item) {
task.fromJS(item);
initDatePicker();
taskListViewModel.canCreate(false);
$('#create').css('visibility', 'visible');
}
function handleBackClick() {
taskListViewModel.canCreate(true);
$('#create').css('visibility', 'hidden');
}
function handleSaveClick(item) {
if (item.id == undefined) {
sendAjaxRequest("POST", function (newItem) { //newitem是返回的对象。
taskListViewModel.tasks.push(newItem);
}, null, {
name: item.name,
description: item.description,
finishTime: item.finishTime,
owner: item.owner,
state: item.state
});
} else {
sendAjaxRequest("PUT", function () {
getAllTasks();
}, null, {
id:item.id,
name: item.name,
description: item.description,
finishTime: item.finishTime,
owner: item.owner,
state: item.state
});
}
taskListViewModel.canCreate(true);
$('#create').css('visibility', 'hidden');
}
function sendAjaxRequest(httpMethod, callback, url, reqData) {
$.ajax("/api/tasks" + (url ? "/" + url : ""), {
type: httpMethod,
success: callback,
data: reqData
});
}
var initDatePicker = function() {
$('#create .datepicker').datepicker({
autoclose: true
});
};
$('.nav').on('click', 'li', function() {
$('.nav li.active').removeClass('active');
$(this).addClass('active');
});
$(document).ready(function () {
getAllTasks();
// 使用KnockoutJs进行绑定
ko.applyBindings(taskListViewModel, $('#list').get(0));
ko.applyBindings(task, $('#create').get(0));
});
@Model IEnumerable<KnockoutJSSPA.Models.Task>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Description</td>
</tr>
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有