MVC 4 Razor使用Ajax表单更新foreach循环

9

从哪里开始呢...我在互联网上能找到类似的内容,但它们似乎从未与我想要做某事的特定方式起作用。我尝试过使用和不使用部分视图,但成功率很低。

快速概述:我有一个带有Ajax表单的强类型视图。在表单下面,我有一个foreach循环,重复一个代码块。我需要能够根据表单的选择(筛选器)更新代码块。

这是我的视图,“FindATeacher.cshtml”的当前状态(尝试了许多不同的想法后):

@model Teachers.Models.OmniModel
@{
    ViewBag.Title = "FindATeacher";
    Layout = "~/Views/Shared/_Layout.cshtml";

}
<h2>Find a Teacher</h2>
@using (Ajax.BeginForm("FilterTeachers", "Home", new AjaxOptions { HttpMethod = "Post", OnSuccess = "onSuccess" }))
{
    <div id="ContentFilter">
        <div class="filterLabels">
            <p>Search by Name</p>
            <p>Filter By Instrument</p>
            <p>Filter By City</p>
        </div>
        <div class="filterObjects">
            <p>
                <input type="text" id="nameTXT" />
                <button type="submit" id="findButton">find</button>
            </p>
            <p>@Html.DropDownList("InstrumentID", (SelectList)Model.Instruments, "-- Select an Instrument --", new { id = "instrumentDD" })</p>
            <p>@Html.DropDownList("CityID", (SelectList)Model.Cities, "-- Select a City --", new { id = "cityDD" })</p>
        </div>
    </div>
}
<hr />
@foreach (var r in Model.Teachers)
{
    <div id="ContentResults">
        <div id="avatar">
            <img src="i" />
        </div>

        <div id="demographics">
            <h6>@r.Teacher</h6>
            <strong>@r.StudioName</strong>
            <p><a href="#">@r.URL</a></p>
            <p>@r.StreetAddress</p>
            <p>@r.City, @r.AddressStateID @r.Zip</p>
            <p>@r.Phone</p>
            <p>@r.EmailAddress</p>
        </div>
        <div id="studioDetails">
            <p><strong>Instrument(s) Taught</strong></p>
            <p>
                @{
    var instrumentString = r.Instruments.Aggregate("", (a, b) => a + b.Instrument + ", ");
    if (instrumentString.Length != 0)
    {
        instrumentString = instrumentString.Remove(instrumentString.LastIndexOf(","));
    }
                }
                @instrumentString
            </p>
            <br />

            @if (r.Information != "" && r.Information != null)
            {
                <p><strong>Information</strong></p>
                <p>@r.Information</p>
            }
        </div>
    </div>
}

现在,这是我的控制器。我在控制器中正确地获取了结果,但代码块没有更新:

public ActionResult FindATeacher()
        {
            Model.Instruments = new SelectList(TeacherService.GetInstrumentList(0),"InstrumentID","Instrument");
            Model.Cities = new SelectList(TeacherService.GetCityList(),"CityID","City");
            Model.Teachers = TeacherService.GetTeacherList("", 0);
            return View(Model);
        }

        [HttpPost]
        public JsonResult FilterTeachers(String teacherName, String instrumentID, String cityID)
        {
            Model.Teachers = TeacherService.GetTeacherList("John", 0, 0);
            return Json(Model.Teachers);
        }

谢谢。
2个回答

14

@VishalVaishya提出了正确的想法,但有一种更简单的方法,不需要自定义JavaScript代码:AjaxOptions有一个UpdateTargetId属性,AJAX工具包将解释为您希望给定的目标使用从控制器返回的结果进行更新。

FindATeacher.cshtml:

@using (Ajax.BeginForm("FilterTeachers", "Home", new AjaxOptions { 
    HttpMethod = "Post", UpdateTargetId = "TeacherList" }))
{
    ...
}
<hr />
<div id="TeacherList">
    @Partial("TeacherList", Model.Teachers)
</div>

教师列表.cshtml

@model IEnumerable<Teacher>
@foreach(var teacher in Model)
{
   ...
}

控制器动作:

    [HttpPost]
    public ActionResult FilterTeachers(String teacherName, String instrumentID, String cityID)
    {
        Model.Teachers = TeacherService.GetTeacherList(teacherName, instrumentID, cityID);
        return PartialView("TeacherList", Model.Teachers);
    }

2
TeacherList.cshtml 是一个局部视图,对吧?在控制器中应该是 return PartialView("TeacherList", Model.Teachers); 对吗? - Haritha
不幸的是,这并没有起作用。当我点击发送按钮时,我没有收到错误提示,但我也没有得到应该得到的结果。什么都没有改变。 - Keltanis
1
使用浏览器的开发工具检查网络流量和JavaScript控制台。 部分视图是否在AJAX调用中得到渲染和返回? 是否有任何错误记录到控制台中? - StriplingWarrior
@StriplingWarrior 我没有尝试过这个,但是动作参数是否匹配呢?我的意思是从表单中发布3个参数是否有效?或者在动作中我们应该使用Teachers模型来捕获它? - Vishal Vaishya
其实,我的问题是我太蠢了 :-) 在我的控制器中,我的局部视图拼写错误。现在完美运行! - Keltanis
有没有人可以提供一下这个示例中使用的模型的例子? - Dscoduc

3
您可以尝试以下方法:
将您的 foreach 循环分离到另一个部分视图中。 在过滤器 / 单击事件上加载您的部分视图,并将过滤参数传递给控制器操作。
JS 更改事件代码将类似于以下内容:
var teacherName = ''; //get your selected teachername
var instrumentID = ''; //get your selected instrumentid
var cityID = ''; //get your selected city id

var url = '@Url.Action("FilterTeachers", "ControllerName", new { teacherName = "teacher-Name", instrumentID="instrument-ID", cityID="city-ID" })';

url = url.replace("teacher-Name", teacherName).replace("instrument-ID", instrumentID).replace("city-ID", cityID);

$('#result').load(url);

鉴于上述方法似乎不起作用,除非出现其他解决方案,否则我将不得不今天尝试这个方法。在上面的解决方案中,在初始创建时,我有两个条目。部分控制器返回一个过滤器条目,但两个条目仍然显示。希望Vishal编写的第一个解决方案有效 :-) - Keltanis
没有尝试这个,因为 Stripling 的效果很棒。 - Keltanis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接