65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 ASP.NET MVC 的待办事项列表

2009年5月25日

LGPL3

4分钟阅读

viewsIcon

34764

使用 MVC 创建任务列表。

引言

MVC 发布已经有一段时间了。在本文中,我将通过 ASP.NET MVC 示例出一个用于管理任务(待办事项列表)的应用程序。第一个 Alpha 版本是针对 MVC 的原生功能编译的,以展示其原生功能。未来的版本将包含 jQuery 插件和完整的基于 DAL 的待办事项列表。您可以在此处观看实时演示并下载代码。

待办事项列表(Index 操作)已使用 jquery dataTable 插件更新。感谢Matt Berseth提供的 iTunes 主题用于 GridView ,该主题已被修改并改编用于 dataTable。屏幕截图如下: 

index.png

背景

在开始编码之前,请先掌握 MVC 模式,并从ASP.NET下载 Visual Studio 2008 附加组件。您可以从 ASP.NET 网站上的各种视频和教程中获得启发。

之前的版本只使用了原生 MVC,即没有向项目中添加数据层。现在,如果您查看源代码,您会发现代码更加有条理(尽管注释不少!)。但 Controller 甚至不知道自己在做什么,只知道实体(TaskItem)。这次更新的文章更有价值的是,根据本次发布,使用代码部分几乎全部重写了。

在继续深入之前,让我们先看看解决方案提供了什么!以下是数据项目的一个快速概览。

Data project

Using the Code

实体已从 ToDoItem重命名为 TaskItem ,但 Controller 名称已保留不变,以保持 URL 不变。让我们看看 Model 中实体类的代码。

  public partial class TaskItem
  {
    public int ItemId { get; set; }
    public string Title { get; set; }
    public int Priority { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? DueDate { get; set; }
    public int? PercentCompleted { get; set; }
    public bool? TrackProgress { get; set; }
    public bool? RemindOnDelay { get; set; }

    #region object overrides
    public override bool Equals(object obj)
    {
      if (obj is TaskItem)
      {
        TaskItem item = (TaskItem)obj;
        return item.ItemId == this.ItemId;
      }

      return base.Equals(obj);
    }

    public override string ToString()
    {
      return this.Title;
    }

    public override int GetHashCode()
    {
      return this.ItemId.GetHashCode();
    }
    #endregion
  }

此 IQuerable 模式实现的功劳归于 Rob Conery。如果您想了解有关 IQueryable 和 todolist 所用模式的更详细教程,Rob 在其博客上发布了关于 MVC Storefront 应用程序的视频教程。您可以在此处观看它们。

对于这个部分类,我们添加了验证逻辑,这样 Controller 端就不再需要进行验证,而是所有验证都在数据层完成。以下代码会检查代码中的任何违规(验证错误)。

  public partial class TaskItem
  {
    public bool IsValid
    {
      get { return (GetRuleViolations().Count() == 0); }
    }

    public IEnumerable<RuleViolation> <code>GetRuleViolations()</code>
    {
      if (string.IsNullOrEmpty(Title))
        yield return new RuleViolation("Task title is required.", "Title");

      if (Priority <= 0 || Priority > 3)
        yield return new RuleViolation("Priority must lie between 1 to 3.", "Priority");

      if (DueDate != null && DueDate < StartDate)
        yield return new RuleViolation
		("Due date must be greater than start date.", "Due Date");

      if (PercentCompleted != null && (PercentCompleted <= 0 || PercentCompleted > 100))
        yield return new RuleViolation
		("Please specify Percentage completed between 1 to 100.",
            "Percentage Completed");

      yield break;
    }
  }

GetRuleViolations函数将帮助我们在数据层为实体操作添加验证检查。感谢 Scott Guthrie 等人撰写了《Professional ASP.NET MVC》(一本很棒的书!)。

正如下面的 InsertTaskItem函数所示,我们可以非常轻松地检查操作中的验证错误。

    /// <summary>
    /// Insert the param to database.
    /// </summary>
    /// <param name="item">TaskItem object to be inserted.</param>
    public void InsertTaskItem(TaskItem item)
    {
      if (!item.IsValid)
        throw new ArgumentException();

      using (LinqTaskItemDataContext db = new LinqTaskItemDataContext())
      {
        SqlRepository.TaskItem dbItem = db.TaskItems
          .Where(x => x.ItemID == item.ItemId)
          .SingleOrDefault();
        bool isNew = false;

        if (dbItem == null)
        {
          dbItem = new DevOrigin.ToDoList.Data.SqlRepository.TaskItem();
          isNew = true;
        }

        int itemId = (from taskItem in db.TaskItems
                      select taskItem.ItemID).Max();

        //add the item
        dbItem.ItemID = ++itemId;
        dbItem.Title = item.Title;
        dbItem.Priority = item.Priority;
        dbItem.StartDate = item.StartDate;
        dbItem.DueDate = item.DueDate;
        dbItem.PercentCompleted = item.PercentCompleted;
        dbItem.TrackProgress = item.TrackProgress;
        dbItem.RemindOnDelay = item.RemindOnDelay;

        if (isNew)
          db.TaskItems.InsertOnSubmit(dbItem);

        db.SubmitChanges();
      }
    }

现在,Service 层项目仅实现 ITaskItemService接口。Service 类使用 ITaskItemRepository方法为其用户提供服务。

正如您在 Controller 方法中看到的,代码已简化为一两行。所有实现都隐藏在数据层中,因此可以轻松更改,而不会影响其上层的层,只要输出保持不变。

哦,我忘了提,如何在 Index controller 中获得漂亮的数据外观?很简单,对吧!我使用了 dataTable jQuery 插件来实现这一点,然后进行了一些样式设计,使其看起来更漂亮。让我们看看 Index 视图中用于 dataTable 的代码。

  <script type="text/javascript" charset="utf-8">
    var oTable;
    var giRedraw = false;
    
    $(document).ready(function() {
      /* Add a click handler to the rows - this could be used as a callback */
      $("#taskList tbody").click(function(event) {
        $(oTable.fnSettings().aoData).each(function() {
          $(this.nTr).removeClass('row_selected');
        });
        $(event.target.parentNode).addClass('row_selected');
      });

      oTable = $('#taskList').dataTable({
        "bAutoWidth": false,
        "bFilter": false
      });
    });

    /* Get the rows which are currently selected */
    function fnGetSelected(oTableLocal) {
      var aReturn = new Array();
      var aTrs = oTableLocal.fnGetNodes();

      for (var i = 0; i < aTrs.length; i++) {
        if ($(aTrs[i]).hasClass('row_selected')) {
          aReturn.push(aTrs[i]);
        }
      }
      return aReturn;
    }
  </script>

突出显示的代码将实际在 View 中渲染 dataTable 。您还会注意到已注册了一个处理程序,用于在用户单击表格中的任何行时选择该行。还有一个未使用的函数 fnGetSelected ,用于将选定的行返回,它是为将来使用而设计的。您可以在此处获得 dataTable 的完整参考。

当您尝试创建一个新任务时,会收到一个需要输入的项目列表,它们是:标题、优先级、开始日期、截止日期、完成百分比、跟踪进度和显示提醒。

有趣的是,“显示提醒”或 ReminderOnDelay,如果任务延迟达到设定的配置标准,将自动向任务所有者发送电子邮件,虽然尚未实现,但可以轻松实现。ToDoList 将向您展示如何做到这一点。

接下来的计划是为todolist添加增强功能和剩余功能。

关注点

一旦您从网站下载了代码,您会找到 schema.sql 文件,借助该文件,您将能够配置数据库。数据库配置完成后,更新 web.config 文件,以便正确反映连接字符串。

历史

  • 0.1.3 (alpha)
    • 已更新为 Repository 和 Queryable 模式
    • 可在 MSDN、Scott Gu 的博客、Rob Corney 的博客上找到
  • v0.1.2 (alpha)
    • 为 Detail 操作更新了 jQuery 插件
  • v0.1 (alpha)
    • 首次发布
© . All rights reserved.