ASP.Net MVC 5通过ajax加载列表数据

3

我在ASP.NET MVC 5中有一个列表。

我限制了每页显示的记录数。

现在,当我滚动时,我会进行Ajax调用。第一次调用很好,但是当我向下滚动更多时,它会重复调用函数5到10次,并再次丢失显示数据,这真的很奇怪,我找不到解决方案。

我的控制器:

public ActionResult Index()
{
    int starting = 0;
    if (Request.Form["starting"] != null)
    {
        starting = Convert.ToInt32(Request.Form["starting"]);
    }

    int takes = 15;
    if (Request.Form["takes"] != null)
    {
        takes = Convert.ToInt32(Request.Form["takes"]);
    }
    //string strpost = "&ajax=1";

    var query = db.MyEmployee.ToList().Skip(starting).Take(takes);


    if (Request.IsAjaxRequest())
    {

        starting = starting+15;
        query = db.MyEmployee.ToList().Skip(starting).Take(takes);
        ViewData["starting"] = starting;
        ViewBag.takes = takes;
        return PartialView("_PartialIndex",query);
    }
    ViewBag.starting = starting;
    ViewBag.takes = takes;
    return View(query);

}

我的模型:

     public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
}

我的视图和部分视图代码:

 <div id="mypage">
@model IEnumerable<MVC5WAuth.Models.Employee>

@{
    ViewBag.Title = "Index";
}

<h2>Index 1</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Id)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.FullName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Email)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FullName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Email)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>


<script type="text/javascript">


    $(window).scroll(function () {
        if ($(window).scrollTop() == $(document).height() - $(window).height()) {
            // ajax call get data from server and append to the div



            var ajax_image = "<img src='../Content/loading.GIF' >";
            $('#mypage').html(ajax_image);
            var params = '&starting=' + @ViewBag.starting + '&takes=' + @ViewBag.takes;
            $.ajax({
                url:'@Url.Action("Index", "Employees")',
                type: "POST",
                data: params,

            })
            .done(function (r) {

                $('#mypage').html(r);
            });

        }
    });

</script>


1
在您的JavaScript函数中使用ViewBag将永远不会更新,因为它不会作为AJAX调用的一部分重新加载。我建议在JS中持久化一个变量,您可以在每个AJAX调用上递增它。 - Chris Pickford
1
你的脚本正在使用 @ViewBag.starting@ViewBag.takes,它们是在第一次生成视图时的初始值(仅因为你在方法中再次设置它们并不会更新它们)。你需要将这些值作为 JavaScript 变量来维护,并对它们进行递增。 - user3559349
从我看来,你没有在JS中更改你的“starting”变量。这就是为什么你一次又一次地得到相同的数据。而且,在前面的几行中可能会有5-10个调用出现计算错误。 - teo van kot
不,我不会一遍又一遍地获取相同的数据。如果你看一下我的函数,在 Request.isAjax 下,我设置了 starting = starting+10,这个方法是有效的,但它会重新加载页面。如果你只是复制粘贴我的代码,你会发现它。 - MJ X
你说的是 _My View partial view 代码_。那真的只是你的 Index.cshtml 视图吗?(这可以解释这种行为) - user3559349
显示剩余5条评论
1个回答

1
您当前的代码只是在每次滚动并进行ajax调用时替换现有视图,而不是使用您想要的下一组行更新现有视图。您的代码也存在一些低效性,例如在调用.Skip().Take()之前将所有记录实例化为内存集合。
您需要将其拆分为两个单独的方法和视图,一个用于生成初始视图,另一个返回部分记录以附加到主视图。
控制器
public ActionResult Index()
{
    return View();
}
public ActionResult Fetch(int startIndex)
{
    query = db.MyEmployee.OrderBy(x => x.ID).Skip(startIndex).Take(15);
    return PartialView(query);
}

Index.cshtml

@model IEnumerable<MVC5WAuth.Models.Employee>
....
<table class="table">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.Id)</th>
            ....
        </tr>
    </thead>
    <tbody id="tbody">
        @{ Html.RenderAction("Fetch", new { startIndex = 0 }); } // generate the 1st 15 rows
    </tbody>
</table>

<script type="text/javascript">
    var start = 15;
    var url = '@Url.Action("Fetch")';
    var tbody = $('#tbody');
    $(window).scroll(function () {
        if ($(window).scrollTop() == $(document).height() - $(window).height()) {
            ....
            $.get(url, { startIndex: start }, function(response) {
                tbody.append(response);
                start += 15; // increment for next call
            });
        }
    });
</script>

Fetch.cshtml

@model IEnumerable<MVC5WAuth.Models.Employee>
@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(m => item.Id)</td>
        ....
    </tr>
}

在第一次加载时,它调用了两个函数,我的意思是将Index函数视图列表数据和fetch函数部分视图数据一起呈现在一个视图中。 - MJ X
谢谢你的帮助,我最终按照你的方法解决了这个问题。 - MJ X

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