【问题标题】:How do I retrieve a viewmodel from another viewmodel?如何从另一个视图模型中检索视图模型?
【发布时间】:2018-05-23 15:33:11
【问题描述】:

我有这个 ViewModel,其中包含 3 个其他视图模型和一个列表:

public class GroupPageViewModel{
    public string GroupName { get; set; }
    public GroupSelectViewModel _groupSelectVM {get; set;}
    public List<User> _users { get; set; }
    public ViewModelStudent _studentVM { get; set; }
    public ViewModelGroupMembers _groupMembersVM { get; set; }
}

在视图中,我可以通过Model._groupSelectVM 访问每个sub-ViewModels,每个sub-ViewModels 都与一个局部视图相关联。当我只需要刷新一个或两个部分视图时,问题就出现了,我不确定如何访问在 Ajax 成功中返回的内部 ViewModel,而且我一般对 MVC 和 asp.net 还比较陌生。我对 JavaScript、jquery 或 Ajax 几乎一无所知。

如何在 Ajax 成功中从主 ViewModel 获取特定的 ViewModel

这只是要求澄清的一个例子,所有其他的都几乎相同(尽管其中一些可能需要更新多个部分视图 -

从控制器:

[HttpPost]
public ActionResult Index(string groupChoice = "0", string newGroup = "")
    {
        string groupName = "";

        if (groupChoice == "0" && newGroup != "")
        {
            if (ModelState.IsValid)
            {
                Group group = new Group
                {
                    GroupName = newGroup,
                    Active = true
                };

                db.Groups.Add(group);
                db.SaveChanges();
                PopulateLists();
            }
        }
        else if (groupList == null)
        {
            groupList = (List<SelectListItem>)Session["groupList"];                
            Session["groupName"] = groupName = groupList.Where(m => m.Value == groupChoice).FirstOrDefault().Text;
            MembersInSpecificGroup(groupName, groupMembers, groupMembersList);
            groupPageVM._groupMembersVM = groupMembers;
        }

        return View("GroupSelection", groupPageVM);
    }

脚本:

$(document).ready(function () {
        $('#selectedGroup').change(function () {
            var data = {
                groupChoice: $('#selectedGroup').val()
            };

            var groupChoice = $('#selectedGroup').val();
            $.ajax({
                url: '/Group/Index/',
                type: 'POST',
                data: { groupChoice: groupChoice },
                success: function (data) {
                    setTimeout(function () {
                        delayGroupSuccess(data);
                    }, delay);

                }
            });
        })
    });
    function delayGroupSuccess(data) {
        $("#groupSelect").html(data);
    }

主页:

@model EMBAProgram.ViewModels.GroupPageViewModel 
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }


<h2>Group Selection</h2>

<div class="row" id="groupSelect">
  @{ Html.RenderPartial("_GroupSelect", Model._groupSelectVM);}
</div>

<hr size="5" />

<div style="display: flex;">
  <div>
    @{Html.RenderPartial("_Students", Model._studentVM);}
  </div>
  <div>
    @{ Html.RenderPartial("_GroupMembers", Model._groupMembersVM);}
  </div>
  <div>
    @{ Html.RenderPartial("_Users", Model._users);}
  </div>
  <br style="clear: left;" />
</div>

局部视图:

@model EMBAProgram.ViewModels.ViewModelGroupMembers


<div class="table-responsive" id="groupResults">
  <table class="table table-condensed table-responsive">
    <thead>
      <tr>
        <th>@Html.DisplayName("M-Number")</th>
        <th>@Html.DisplayName("Name")</th>
        <th>@Html.DisplayName("Student")</th>
      </tr>
    </thead>
    <tbody>
      @foreach (var item in Model._groupVM) {
      <tr>
        <td>@Html.DisplayFor(m => item.MNumber)</td>
        <td>@Html.DisplayFor(m => item.Name)</td>
        <td>@Html.DisplayFor(m => item.Student)</td>
      </tr>
      }
    </tbody>
  </table>
</div>

基本上,我需要能够从主 ViewModel(我相信这是 Ajax 中返回的内容)中提取部分视图的 ViewModel,并刷新部分视图。

【问题讨论】:

  • 您的 ajax 调用返回什么?你想做什么?您的预期行为是什么? (包括问题的相关代码)

标签: javascript jquery asp.net-mvc asp.net-mvc-5 asp.net-ajax


【解决方案1】:

我删除了原始答案,如果人们想看到它,我认为它可以在编辑日志中找到。但它占用了太多空间并且不正确。


您可以返回多个部分视图,我认为这是将它们转换为字符串的内置方式(我的评论很着急),但我有一个可行的示例。

在控制器中我有以下内容:

public ActionResult Index()
{
    var model = new TestViewModel
    {
        Students = GetStudents(),
        Categories = GetCategories(),
        Groups = GetGroups()
    };

    return View("Index", model);
}

// Returns multiple partial views as strings.
public ActionResult StudentsAndGroups()
{
    return Json(new
    {
        Students = RenderRazorViewToString("_Students", GetStudents()),
        Groups = RenderRazorViewToString("_Groups", GetGroups())
    }, JsonRequestBehavior.AllowGet);
}

// Creates a string from a Partial View render.
private string RenderRazorViewToString(string viewName, object model)
{

    ControllerContext.Controller.ViewData.Model = model;

    using (var stringWriter = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        var viewContext = new ViewContext(ControllerContext, viewResult.View, ControllerContext.Controller.ViewData, ControllerContext.Controller.TempData, stringWriter);
        viewResult.View.Render(viewContext, stringWriter);
        viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
        return stringWriter.GetStringBuilder().ToString();
    }
}

我的主索引视图如下所示:

<button class="refresh">Refresh</button>

<div class="row">
    <div class="col-md-4 students">
        @{
            Html.RenderPartial("_Students", Model.Students);
        }
    </div>

    <div class="col-md-4">
        @{
            Html.RenderPartial("_Category", Model.Categories);
        }
    </div>

    <div class="col-md-4 groups">
        @{
            Html.RenderPartial("_Groups", Model.Groups);
        }
    </div>
</div>

@section scripts
{
    <script type="text/javascript">
        $(".refresh").click(function () {
            $.get("/Home/StudentsAndGroups", function (d) {
                $(".students").html(d.Students);
                $(".groups").html(d.Groups);
            })
        });
    </script>
}

控制器动作 StudentAndGroups 将两个部分视图转换为字符串。从那里,javascript 调用该视图并访问元素并返回它们。

在这里找到了将视图渲染为字符串的辅助方法:https://stackoverflow.com/a/34968687/6509508

【讨论】:

  • 这基本上是我现在设置的方式,当我需要刷新多个局部视图时出现问题..即学生和组员同时进行。因为 actionresult 不会返回多个模型,所以我不能使用一个控制器方法来更新多个视图,除非另一个 ViewModels 打包在一起并在主视图中拆分。
  • 多请求怎么办?为您要更新的每个部分执行一个操作,并按顺序调用它们。
  • 此外。您可以返回多个视图。考虑以下内容:return Json(new { Groups = RenderViewToString(PartialView("_GroupMembers", groupMembers), Students = RenderViewToString(PartialView("_Students", studentData) }); 然后在您的 javascript 中,您可以像下面这样访问它:function (data) { $("...").html(data.Students); $("...").html(data.Groups); } 注意:您可能需要执行一些 JSON 反序列化才能使 HTML 正常工作。我不是 100% 如果它会像上面那样工作,但这应该会让你走上正确的道路。
  • 关于您的编辑,我添加了错误的脚本,即针对其他内容。但是另一个脚本本质上是一样的,它只是针对#groupResults。
  • 我会尝试一下,希望它有效,我会在尝试后更新。感谢您的帮助。
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-24
  • 2017-08-28
  • 1970-01-01
  • 2017-04-11
  • 2011-10-21
相关资源
最近更新 更多