如何从另一个视图模型中检索视图模型?

时间:2017-12-09 16:05:30

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

我有这个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; }
}

在视图中,我可以sub-ViewModels访问这些Model._groupSelectVM中的每一个,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并刷新局部视图。

1 个答案:

答案 0 :(得分:0)

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

你可以返回多个局部视图,我认为它是一种内置的方式来将它们变成一个字符串(我在评论中匆匆忙忙),但我有一个有效的例子。

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

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

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

在此处找到了将视图呈现为字符串的帮助方法:https://stackoverflow.com/a/34968687/6509508