三、在控制器中加入AJAX支持技术
在此,我们要做的第一件事情是从AjaxController类(而不是直接从Controller类)中派生类TaskListController。
AjaxController是我刚刚添加的一个类,此类引入了一个新的属性IsAjaxRequest。我在自己的Action方法中就使用这个属性来完成诸如生成不同视图之类的任务。此外,它还引入了一些成员函数,例如RenderPartial。这个RenderPartial函数可以用于生成定义在一个部分视图中的用户接口的一部分。下面给出修改后的控制器以及新修改的Add方法(其中修改部分及添加部分均以粗体显示):
public void Add(string name) {
Task newTask = null;
if (String.IsNullOrEmpty(name) == false) {
newTask = _taskDB.AddTask(name);
}
if (IsAjaxRequest) {
if (newTask != null) {
RenderPartial("TaskView", newTask);
}
}
else {
if (newTask != null) {
RedirectToAction("List");
}
else {
Dictionary<string, object> viewData = new Dictionary<string, object>();
viewData["Tasks"] = _taskDB.GetTasks();
viewData["ShowAddTaskError"] = true;
RenderView("List", viewData);
}
}
}
}
接下来,我把TaskView重新定义为一个自定义控件TaskView.ascx(位于/Views/TaskList文件夹下),代码如下所示:
<form method="post" action='<%= Url.Action("CompleteTask") %>'>
<input type="hidden" name="taskID" value="<%= Task.ID %>" />
<input type="submit" name="completeTask" value="Done!" />
<input type="submit" name="deleteTask" value="Delete" />
<span><%= Html.Encode(task.Name) %></span>
</form>
</div>
其实,上面的代码仅仅是前面介绍的List.aspx的简单重构(所以,你可能看上去十分熟悉这段代码)。相应于这个用户控件的ViewData是一个Task类的实例。现在,既然我们已经定义了这一部分,那么接下来我们就可以从本例主要的视图页面List.aspx中使用它了。这一点是借助于前面我提供的RenderPartial扩展方法实现的。一旦做到这些,视图List.aspx的任务列表部分将变为:
<% foreach (Task task in Tasks) { %>
<div>
<% this.RenderPartial("TaskView", task); %>
</div>
<% } %>
</div>
接下来,我需要让此视图发出XMLHttp请求而不是一个传统的表单提交。再次,我提供了一些扩展方法:
⑴RenderBeginForm描述的是一个普通的表单标签;
⑵RenderBeginAjaxForm将负责生成一个支持AJAX功能的表单(这正是我们的兴趣点所在);
⑶RenderEndForm。
借助于这些方法,实现添加任务的UI表单标签部分看上去如下加粗部分所示:
new { Update="taskList, UpdateType="appendBottom",
Highlight="True",
Starting="startAddTask", Completed="endAddTask" }); %>
<input type="text" name="name" />
<input type="submit" name="addTask" value="Add Task" />
<% RenderEndForm(); %>