部分视图使用的是不同的模型而不是包含在其中的页面?

时间:2014-06-02 21:24:20

标签: jquery asp.net-mvc model viewmodel partial-views

我的主页面中有一个局部视图,它使用的模型与主页面使用的模型不同。

简而言之,我的主页上有一个下拉控件,它使用一个模型来填充其选项。当选择一个选项时,我有一个脚本将所选选项发布到家庭控制器中的另一个操作方法。该方法获取该值,并运行依赖于该值的db查询。然后我将这些结果放入模型中,并将该模型传递给我的局部视图。呈现局部视图,然后转换为HTML标记并将其传递回JSON对象中的脚本。然后,脚本将生成的视图标记写入主页面中的div。

我的问题是我得到一个错误,说局部视图正在寻找一个模型,当它获得的模型是主页的模型 - 而不是它自己的模型。有一种简单的方法可以解决这个问题吗?我无法将这两个模型包装在另一个模型(视图模型)中,因为这两个模型通过不同的操作方法传递。

以下是希望提供帮助的相关代码:

控制器

public class HomeController : Controller
{
    // Loaded when page first requested. Displays a dropdown with all
    // distinct sampling events.
    public ActionResult Index()
    {
        // Set page title
        ViewBag.Title = "Sample Tracker Tool";
        // Calculate range filter for samples
        DateTime nineMonthsAgo = DateTime.Now.AddDays(-270);

        // Retrieve sampling events within filter range
        var context = new EDMS_Entities();
        var resultSet = (from samplingEvents in context.EDMS_SAMPLES
                         where samplingEvents.RECORD_CREATED_DATE >= nineMonthsAgo
                         orderby samplingEvents.SAMPLING_EVENT
                         select samplingEvents.SAMPLING_EVENT).Distinct();

        // Create viewmodel for sampling events dropdown use
        var viewModel = new SamplingEventsVM();
        viewModel.SamplingEvents = new SelectList(resultSet);

        return View(viewModel);
    }

    // When the selected sampling event is changed, jQuery posts the selected value
    // to this method. The selected value is used to return all samples for the
    // selected sampling event.
    public ActionResult RetrieveSamples(string samplingEvent)
    {
        // This currently just returns the selected sampling event
        // TODO: Use sampling event to retrieve all samples and construct a list of
        // Sample objects for the selected sampling event. These samples will be used
        // to display the sample's list of analytes.

        // Retrieve samples for selected sampling event
        // **Samples query in progress...**
        // TODO: Finish constructing the full query
        var context = new EDMS_Entities();
        var resultSet = from samples in context.EDMS_SAMPLES
                        join stations in context.EDMS_SAMPLE_STATIONS on samples.STATION_SEQ equals stations.STATION_SEQ
                        where samples.SAMPLING_EVENT == samplingEvent
                        select new { samples.SAMPLE_ID, stations.STATION_ID, samples.COLLECTION_DATE, samples.COMMENTS };

        // Assign results to model objects and add resulting model objects to the ObservableCollection instance "sampleResults"
        ObservableCollection<Sample> sampleResults = new ObservableCollection<Sample>();
        foreach(var row in resultSet)
        {
            var newSample = new Sample(row.SAMPLE_ID, row.STATION_ID, row.COLLECTION_DATE, row.COMMENTS);
            sampleResults.Add(newSample);
        }

        // Pass sample objects to partial view and parse HTML markup from rendered partial view
        var partialViewHtml = RenderViewToString(this.ControllerContext, "~/Views/Home/RetrieveSamples.cshtml", sampleResults);

        // Add partial view HTML markup to new JsonResult object
        JsonResult result = new JsonResult();
        result.Data = partialViewHtml;

        return result;
    }

    // Convert partial view to HTML string
    private string RenderViewToString(ControllerContext context, string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
        {
            viewName = context.RouteData.GetRequiredString("action");
        }

        var viewData = new ViewDataDictionary(model);

        using (var writer = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
            var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), writer);
            viewResult.View.Render(viewContext, writer);

            return writer.GetStringBuilder().ToString();
        }
    }
}

主视图

<!DOCTYPE html>

<html>
    @using SampleTracking.Models.ViewModels;
    @model SamplingEventsVM
    <head>
        <title>@ViewBag.Title</title>
        <script src="~/Scripts/jquery-2.1.1.js"></script>
        <script type="text/javascript" src="~/Scripts/CustomScripts.js"></script>        
    </head>
    <body>
        <span id="SamplingEventDiv">
            @Html.DropDownListFor(model => model.SelectedSamplingEvent, Model.SamplingEvents, new { @id = "SamplingEventSelection" })
        </span>
        <div id="SamplingEventDetails">
            @Html.Partial("~/Views/Home/RetrieveSamples.cshtml")
        </div>
    </body>
</html>

部分视图

@using System.Collections.ObjectModel;
@using SampleTracking.Models.ViewModels;
@model ObservableCollection<Sample>
<div id="SamplingEventDetails">
    @foreach (var sample in Model)
    {
        <div>sample.SampleID</div>
    }
</div>

2 个答案:

答案 0 :(得分:0)

你试过......

Html.Partial("~/Views/Home/RetrieveSamples.cshtml",new SomeModel())

答案 1 :(得分:0)

所以我认为我已经解决了这个问题 - 事实证明我真的不需要Html.Partial,因为我的脚本无论如何都要将渲染视图作为HTML获取。辅助方法是不必要的。