在jQuery ajax命令之后重新加载部分页面

时间:2013-02-20 04:31:17

标签: c# jquery asp.net-mvc razor

我对JQuery和Asp.net MVC 3(C#)都很陌生,所以如果这是微不足道的话我会道歉。我有一个MVC局部视图(Index.cshtml),它有一个任务列表。这些任务包含在列表样式布局中的indivudal div中。我有一个名为“添加任务”的按钮,可以打开一个对话框。此对话框将通过对控制器的AJAX Json调用将添加的任务保存到数据库。

这是我遇到麻烦的地方 - 在对话框关闭后,我希望用我刚刚添加的任务重新加载任务列表。我找到了重新加载整个页面的示例,并且我找到了控制器应该返回渲染视图的示例。我的问题是从我想要重新加载的部分打开对话框。有没有办法完成我想要做的事情。

Index.cshtml

@model IEnumerable<TaskManagementApplication.Models.Project>

@{
    ViewBag.Title = "Index";
}



<h2>Index</h2>

<div id="ProjectAccordionWrapper">
    @foreach (var item in Model)
    {
        <div class="ProjectWrapper">
            <h3>@item.Name</h3>
            <div class="column">
                <button class="createTaskButton" id="@item.ProjectID">Create New Task</button>
                    @foreach(var task in item.Tasks) {
                        var buttonClass = "taskID" + task.TaskID;
                          <div class="portlet">
                            <div class="portlet-header">@task.TaskName</div>
                            <div class="portlet-content">@task.TaskDescription</div>
                            <button class="editTaskButton" id="@task.TaskID">Edit Task</button>
                          </div>   
                    }
            </div>
        </div>
    }
</div>

<div id="dialog-form" title="Create new user">
  <p class="validateTips">All form fields are required.</p>

  <form>
  <fieldset>
    <label for="TaskName">Task Name</label>
    <input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
    <label for="TaskDescription">Task Description</label>
    <input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
    <input type="hidden" name="TaskID" id="ID" />
    <input type="hidden" name="ProjectID" id="ProjectID" />
  </fieldset>
  </form>
</div>

部分Javascript

function GetTask(id) {
    if (id.length > 0) {
        $.ajax({
            url: '/Project/GetTaskFromID',
            type: "POST",
            data: { "id": id },
            success: PopulateDialogFields,
            error: HandleError
        });
    }
}

function PopulateDialogFields(data) {
    $("#name").val(data.TaskName);
    $("#description").val(data.TaskDescription);
    $("#ID").val(data.TaskID);
}

function HandleError(data) {
    alert(data.error);
    var foo = data;
}

function SaveTask() {
    var taskName = $("#name").val();
    var taskDescription = $("#description").val();
    var id = $("#ID").val();
    var projectID = $("#ProjectID").val();
    if (id.length > 0) {
        $.ajax({
            url: '/Project/SaveTask',
            type: "POST",
            data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
        });
    }
    else {
        $.ajax({
            url: '/Project/SaveTask',
            type: "POST",
            data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
        });

    }
}

$("#dialog-form").dialog({
    autoOpen: false,
    height: 300,
    width: 350,
    modal: true,
    buttons: {
        "OK": function () {
                SaveTask();
                $(this).dialog("close");
        },
        Cancel: function () {
            $(this).dialog("close");
        }
    },
    close: function () {
        allFields.val("").removeClass("ui-state-error");
        window.location.reload(true);
    },
    open: function () {
        var id = $(this).data("id");
        var projectID = $(this).data("projectID");
        $("#ProjectID").val(projectID);
        var button = $("#" + id);
        GetTask(id);
    }
});

$(".editTaskButton")
  .button()
  .click(function () {
      $("#dialog-form").data('id', this.id).dialog("open");
  });

$(".createTaskButton")
  .button()
  .click(function () {
      $("#dialog-form").data('projectID', this.id).dialog("open");
  });

2 个答案:

答案 0 :(得分:0)

我对jQuery和ASP.NET MVC也相对较新,但是,这是首先想到的。

为了维护页面的AJAX-y方面,我建议您创建一个处理POST的方法,该方法返回JSON格式的TaskManagementApplication.Models.Project集。此方法可以选择返回过滤结果。

标记看起来像这样,

<div id="ProjectAccordionWrapper">
    <div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
        <h3 id="itemName"></h3>
        <div class="column">
            <button class="createTaskButton" id="itemProjectID">Create New Task</button>
            <div id="portletTemplate" class="portlet">
                <div class="portlet-header" id="taskName"></div>
                <div class="portlet-content" id="taskDescription"></div>
                <button class="editTaskButton" id="taskID">Edit Task</button>
            </div>   
        </div>
    </div>
</div>

接下来,你将jQuery克隆ProjectWrapperTemplate元素,并设置所有相应的字段。

$(function () {
    $.ajax({
        url: '/Project/GetTasks',
        type: "POST",
        data: { }
    }).done(function (data) {
        data.forEach(function (element) {
            AppendProjectWrapper(element);
        });
    });

    function AppendProjectWrapper(data) {
        var projectAccordionWrapper = $('#ProjectAccordionWrapper');

        var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
        projectWrapper.id = nothing; // remove the id, so as to not have duplicates
        projectWrapper.style.display = nothing; // remove the style "display: none"

        var itemName = projectWrapper.children('#itemName'); // h3
        itemName.id = nothing;
        itemName.text(data.ItemName);

        var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
        itemProjectID.id = data.ItemProjectID;

        var portletTemplate = projectWrapper.children('#portletTemplate'); // div
        data.Tasks.forEach(function (element) {
            var portlet = portletTemplate.clone();
            portlet.id = nothing;

            var taskName = portlet.children('#taskName');
            taskName.id = nothing;
            taskName.text(element.TaskName);

            var taskDescription = portlet.children('#taskDescription');
            taskDescription.id = nothing;
            taskDescription.text(element.TaskDescription);

            var editTaskButton = portlet.children('#taskID');
            editTaskButton.id = element.TaskID;

            portlet.appendTo(projectWrapper);
        });
        portletTemplate.remove(); // remove the portlet template element

        projectWrapper.appendTo(projectAccordionWrapper);
    }
}

最后,让'/Project/SaveTask'返回当前保存任务的JSON格式TaskManagementApplication.Models.Project

$.ajax({
    url: '/Project/SaveTask',
    type: "POST",
    data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
    AppendProjectWrapper(data);
});

'/Project/GetTasks'的返回数据应如下所示:

[
    {
        ItemName: '@item.Name',
        ItemProjectID: '@item.ProjectID',
        Tasks: [
            TaskName: '@task.TaskName',
            TaskDescription: '@task.TaskDescription',
            TaskID: '@task.TaskID'
        ]
    }
]

来自'/Project/SaveTask'的返回数据应遵循相同的格式,但最外层的数组除外。

请注意,很多此类代码未经过测试。

答案 1 :(得分:0)

将列表重构为另一个动作+视图可能最容易。然后,您可以在原始Index.cshtml视图和jQuery中的.load()方法中调用它。所以,假设:

项目控制器

[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
    // create the appropriate model object as an IEnumerable of your Task type

    return View(model);
}

<强> Tasks.cshtml

@foreach(var task in Model) {
    var buttonClass = "taskID" + task.TaskID;
      <div class="portlet">
        <div class="portlet-header">@task.TaskName</div>
        <div class="portlet-content">@task.TaskDescription</div>
        <button class="editTaskButton" id="@task.TaskID">Edit Task</button>
      </div>   
}

您可以像这样调整 Index.cshtml

@model IEnumerable<TaskManagementApplication.Models.Project>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>   
<div id="ProjectAccordionWrapper">
    @foreach (var item in Model)
    {
        <div class="ProjectWrapper">
            <h3>@item.Name</h3>
            <div class="column">
                <button class="createTaskButton" id="@item.ProjectID">Create New Task</button>
                <div id="tasks-@item.ProjectID">
                   @Html.Action("Tasks", "Project", new { id = item.ProjectID })
                </div>
            </div>
        </div>
    }
</div>

    //... the rest of the view

最后,

// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);