简体   繁体   English

使用JQuery将自定义集合对象从Controller传递到View

[英]Pass custom collection object from Controller to View with JQuery

I have a custom object that derives from IEnumerable. 我有一个从IEnumerable派生的自定义对象。 This collection is pretty complex because it contains object which themselves contain collections of other objects. 该集合非常复杂,因为它包含的对象本身也包含其他对象的集合。 Simply put, it is a multiple dimension array. 简而言之,它是一个多维数组。

I have a drop down list on my view that gets populated with a server call of items, and when a certain item is selected, it calls the server to get the associated collection object for that item. 我的视图上有一个下拉列表,其中填充有服务器的项目调用,并且当选择某个项目时,它将调用服务器以获取该项目的关联收集对象。

I inherited this code and initially when the first drop down was selected a second drop down is enabled and the user selects a single item. 我继承了此代码,最初选择了第一个下拉菜单时,启用了第二个下拉菜单,并且用户选择了一个项目。 The second drop down is populated with the items in the collection (the collection itself is parsed through to simply get the name and id number of the item). 第二个下拉列表中填充了集合中的项目(对集合本身进行解析以仅获取项目的名称和ID号)。

Now, instead of a second drop down, I want to actually return the collection to the view and have my view loop through and display the contents of the collection and all that good stuff. 现在,我不想再下拉菜单,而是要真正将集合返回到视图,并让我的视图循环遍历并显示集合的内容以及所有这些好东西。

My question is how can I transfer this collection object from my controller to my view. 我的问题是如何将该集合对象从控制器传输到视图。

Here is the code in the controller which will grab the collection based on the value of the drop down. 这是控制器中的代码,它将基于下拉列表的值获取集合。

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);
    }

This code will return a partial view with the collection as a model. 此代码将返回一个以集合为模型的局部视图。 But how can I use that with the existing JQuery code when the drop down has a value selected? 但是,当下拉列表中选择了一个值时,如何与现有的JQuery代码一起使用呢?

Here is the drop down code: 这是下拉代码:

// 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
    });

I want to make this simple so if there is a better way to do all of this and restructure the controller and/or jquery, I am all ears (eyes). 我想简化一下,所以如果有更好的方法来完成所有这些操作并重组控制器和/或jquery,我将全神贯注。

Let me know if more information is needed or if anything is unclear. 让我知道是否需要更多信息或不清楚。 Thanks 谢谢

"Best practice" here is single responsibility principle, ie separate actions for getting the data that should be displayed in dropdown and the same data that is rendered as partial view. 这里的“最佳实践”是单一责任原则,即用于获取应在下拉菜单中显示的数据和呈现为部分视图的相同数据的单独操作。 Basically all you need is a method to retrieve the model, and one action that serializes the model and return in form of JSON, another - returns partial view. 基本上,您所需要的只是一种检索模型的方法,一个将模型序列化并以JSON形式返回的操作,另一个-返回局部视图。 Controller: 控制器:

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);
}

From client side you must change the url to post data to GetWorkbooks action method and you are good to go. 在客户端,您必须更改URL才能将数据发布到GetWorkbooks操作方法,并且一切顺利。

Advantages of this approach is that populating the dropdown will not execute any other logic than retrieving workbooks list and at client side you can now easily leverage any binding framework (eg KnockoutJS) or plain javascript to render your model, even if your html markup will be changed in future from simple dropdown to more complex ui. 这种方法的优点是,填充下拉列表将不会执行除检索工作簿列表之外的任何其他逻辑,并且在客户端,您现在可以轻松利用任何绑定框架(例如KnockoutJS)或纯JavaScript来呈现模型,即使您的html标记是将来从简单的下拉菜单更改为更复杂的ui。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM