使用JQuery将自定义集合对象从控制器传递到视图

Pass custom collection object from Controller to View with JQuery

本文关键字:控制器 视图 对象 JQuery 自定义 集合 使用      更新时间:2023-09-26

我有一个派生自IEnumerable的自定义对象。这个集合非常复杂,因为它包含的对象本身又包含其他对象的集合。简单地说,它是一个多维数组。

我的视图上有一个下拉列表,它被填充了一个项目的服务器调用,当某个项目被选中时,它调用服务器来获取该项目的相关集合对象。

我继承了这段代码,最初当第一个下拉菜单被选中时,第二个下拉菜单被启用,用户选择单个项目。第二个下拉列表中填充了集合中的项目(通过解析集合本身来获取项目的名称和id号)。

现在,不需要第二个下拉列表,我想把集合返回给视图让视图循环遍历并显示集合的内容等等

我的问题是如何将这个集合对象从我的控制器转移到我的视图。

下面是控制器中的代码,它将根据下拉列表的值获取集合。

public ActionResult GetWorkbooks(string term, int projectId = -1)
    {
        if (this.SelectedProject != projectId)
        {
            try
            {
                WorkBookDataManager dataManager = new WorkBookDataManager();
                this.WorkbookColl = dataManager.GetWorkBooksById(null, projectId, null);
                this.SelectedProject = projectId;
            }
            catch (Exception exc)
            {
                log.Error("Could not load projects", exc);
            }
        }
        return this.View("_Workbook", this.WorkbookColl);
    }

这段代码将返回一个以集合为模型的部分视图。但是,我如何使用现有的JQuery代码,当下拉菜单有一个值选择?

下面是下拉代码:
// Populate the first drop down
var loadProjects = function (request, response) {
    $.ajax({
        url: $("#projects").attr("data-vs-autocomplete"),
        dataType: "json",
        type: "POST",
        data: { term: request.term }
    })
    .always(function (data, status) { getResponse(response, data, status); });
};
// If the first drop down has an item selected enable the second drop down
var projectSelected = function (event, ui) {
    var projectId = $("#projects").data(VS_AUTOCOMPLETE_VALUE);
    var enable = projectId ? false : true;
    /*$("#workbooks").prop('disabled', enable);
    $("#workbooks").val("");
    $("#workbooks").data(VS_AUTOCOMPLETE_VALUE, "");
    $("#workbooks").data(VS_AUTOCOMPLETE_TEXT, "");*/
    $("#workbook").html("<p>No workbook selected</p>");
};
// Function to get the second drop down items
// This is the function I think needs to be modified to accept the collection object from the server
var loadWorkbooks = function (request, response) {
    $.ajax({
        url: $("#workbooks").attr("data-vs-autocomplete"),
        dataType: "json",
        type: "POST",
        data:
            {
                term: request.term,
                projectId: $("#projects").data(VS_AUTOCOMPLETE_VALUE)
            }
    })
        .always(function (data, status) { getResponse(response, data, status); });
};
// Second drop down -> This needs to be removed
var workbookSelected = function (event, ui) {
    $("#workbooks").blur(); // this prevents the workbook dropdown from focusing.
    LoadWorkbook();
};

// These functions populated the drop downs with items
Autocomplete($("#projects"),
   { autoFocus: true,
       minLength: 0,
       source: loadProjects,
       select: projectSelected
   });
Autocomplete($("#workbooks"),
    { autoFocus: true,
        minLength: 0,
        source: loadWorkbooks,
        select: workbookSelected
    });

我想让它变得简单,所以如果有更好的方法来做这一切,重构控制器和/或jquery,我洗耳恭听。

如果需要更多的信息或者有什么不清楚的,请告诉我。由于

这里的"最佳实践"是单一责任原则,即单独的操作来获取应该在下拉菜单中显示的数据和呈现为部分视图的相同数据。基本上,您所需要的只是一个检索模型的方法,一个序列化模型并以JSON形式返回的操作,另一个—返回部分视图。控制器:

private Workbook GetWorkbooksByProject(int projectId)
{
    WorkBookDataManager dataManager = new WorkBookDataManager();
    var workbookColl = dataManager.GetWorkBooksById(null, projectId, null);   
    return workbookColl;
}
public JsonResult GetWorkbooks(int projectId)
{
    var model = GetWorkbooksByProject(projectId);
    return Json(model, JsonRequestBehavior.AllowGet);
}
public ActionResult WorkbooksList(string term, int projectId = -1)
{
    if (this.SelectedProject != projectId)
    {
        try
        {
            this.WorkbookColl = GetWorkbooksByProject(projectId);
            this.SelectedProject = projectId;
        }
        catch (Exception exc)
        {
            log.Error("Could not load projects", exc);
        }
    }
    return this.View("_Workbook", this.WorkbookColl);
}

从客户端,你必须更改url以将数据发送到GetWorkbooks动作方法,然后你就可以开始了。

这种方法的优点是,填充下拉菜单不会执行任何其他逻辑,除了检索工作簿列表,在客户端,你现在可以很容易地利用任何绑定框架(例如KnockoutJS)或纯javascript来渲染你的模型,即使你的html标记将来会从简单的下拉菜单更改为更复杂的ui。