【问题标题】:Infinite Scrolling in Asp.Net MVC with jQuery / AJAX Issues带有 jQ​​uery / AJAX 问题的 Asp.Net MVC 中的无限滚动
【发布时间】:2017-08-08 12:41:34
【问题描述】:

我的 ASP.Net (MVC) 应用程序中有无限滚动,尽管有时会出现一些奇怪的行为。

我遇到的问题是,当我滚动时,它似乎不止一次地加载了同一批项目 - 但是,如果我在控制器代码中放置一个断点并减慢它的速度,它就可以正常工作!即使我在我的 jQuery 代码中添加了一个看起来也不错的警报 - 就像我多次滚动触发点并且它调用 ListMore 动作太多次 - 这就是我能想到的一切,就像我说的那样,如果我休息一下指向我的控制器,它会减慢它的速度,我看不到它多次触发!

我在部分视图中放置了一些调试计数器,以便我可以看到它多次加载第 2 页。

我创建了一个局部视图/新控制器方法来检索第 2 页及以后的数据(第 1 页通过主视图控制器方法加载)

public PartialViewResult ListMore(int id = 0, int page = 1, int sort = 0)
{
    int pageSize = AppConstants.PageSize;

    // get the products for this category
    var prods = mgr.GetProducts(id, sort);

    CategoryViewModel model = new CategoryViewModel
    {
        Products = prods
        .Skip((page - 1) * pageSize)
        .Take(pageSize)
    };

    return PartialView("_ListMore", model);
}

局部视图很简单:

@model TooledUp.WebUI.Models.Catalog.CategoryViewModel

@foreach (var item in Model.Products)
{
    <div class="col-1-3">
        @{Html.RenderPartial("_ProductGrid", item);}
    </div>
}

然后我的主视图中有以下内容:

<div class="row clearfix">
    @foreach (var item in Model.Products)
    {
        <div class="col-1-3">
            @{Html.RenderPartial("_ProductGrid", item);}
        </div>
    }
    <div id="listmore"></div>
</div>

<div id="progress" style="display:none;">
    <img src="~/Content/images/Spinner.gif" alt="Loading" /> Loading more     products...
</div>
<div id="progressmarker"></div>

而我的 jQuery / ajax 代码如下(在主视图中) - Model.PagingInfo 的东西仅在调用主视图时设置一次。

<script type="text/javascript">

var categoryId = @Model.CurrentCategoryID;
var pageSize = @Model.PagingInfo.ItemsPerPage;
var pageIndex = 2; // already loaded page 1 - this is next to get
var sortIndex = @Model.PagingInfo.SortBy;
var pages = @Model.PagingInfo.TotalPages;

$(window).scroll(function() {
    var hT = $('#progressmarker').offset().top,
        hH = $('#progressmarker').outerHeight(),
        wH = $(window).height(),
        wS = $(this).scrollTop();
    if ((pages + 1) > pageIndex)
    {
        if (wS > (hT+hH-wH)){
            //alert(pageIndex);
            GetData();
        }
    }
});

function GetData() {
    $.ajax({
        type: 'GET',
        url: '/category/ListMore',
        data: {
            "id": categoryId,
            "page": pageIndex,
            "sort": sortIndex
        },
        dataType: 'html',
        success: function (data) {
            if (data != null) {
                $("#listmore").append(data);
                pageIndex++;
            }
        },
        beforeSend : function () {
            $("#progress").show();
        },
        complete : function () {
            $("#progress").hide();
        },
        error: function () {
            alert("Error while retrieving data!");
        }
    });
}
</script>

当我更改 pageIndex++ 代码的位置时(因为我认为在渲染额外内容之前它的触发速度不够快,因此可能会加载两次相同的内容)它所做的只是以另一种方式破坏它所以快速滚动会使页面(块)被跳过,因此它会增加得太快——从第 2 页跳到第 5 页!

总而言之,我的问题是控制滚动每页(块)只触发一次,但总是针对连续页面触发。

【问题讨论】:

  • 还要检查浏览器中的网络选项卡以查看正在调用的内容。
  • 添加一个标志(比如var isExecuting)来指示ajax调用是否正在执行 - 在$.ajax({之前将其设置为true,然后在成功回调中返回false)。然后在.scroll()处理程序中,如果值为false,则仅调用GetData();
  • 谢谢似乎效果很好!

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


【解决方案1】:

这就是我根据建议最终做的事情:

$(window).scroll(function () {
    var hT = $('#progressmarker').offset().top,
        hH = $('#progressmarker').outerHeight(),
        wH = $(window).height(),
        wS = $(window).scrollTop();
    // don't do it if we have reached last page OR we are still grabbing items
    if (pages >= pageIndex && !_incallback) {
        if (wS > (hT + hH - wH)) {
            GetData();
        }
    }
});

function GetData() {
    _incallback = true;
    $.ajax({
        type: 'GET',
        url: '/category/ListMore',
        data: {
            "id": categoryId,
            "page": pageIndex,
            "sort": sortIndex
        },
        dataType: 'html',
        success: function (data) {
            if (data != null) {
                $("#listmore").append(data);
                pageIndex++;
            }
        },
        beforeSend: function () {
            $("#progress").show();
        },
        complete: function () {
            $("#progress").hide();
            _incallback = false;
        },
        error: function () {
            //alert("Error while retrieving data!");
            _incallback = false;
        }
    });
}

现在看来可以正常工作了,谢谢。

【讨论】:

  • _incallback 定义在哪里?
猜你喜欢
  • 2010-10-09
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
  • 2011-05-13
  • 2014-07-10
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
相关资源
最近更新 更多