只有当页面滚动下来MVC 4 jQuery Mobile的加载数据加载、页面、数据、jQuery

2023-09-10 19:27:37 作者:乜许、

在我看来,我填充从表中有超过1000条记录拍摄内容。我有填充的内容的方式,记录被填充到只有当向下滚动,而不是在一次较少的记录。我用这个开发移动应用程序。我曾尝试与不同来源的在线,但不能有效地滚动的程度。如果你还不清楚我的问题,你们中的大多数可能使用Facebook的。有没有一次性全部装载的职位。滚动只有当他们被加载。我要实现相同的功能。以实时code的任何引用将AP preciated。在此先感谢。

In my view am populating contents taken from a Table which has more than 1000 records. I have to populate the contents in a manner that records are populated to fewer records only when scrolled down and not at once. I use this for developing a mobile application. I have tried with various sources online but not effective to the extent of scrolling. If you are still not clear with my question, most of you might have used facebook. There the posts are not loaded all at once. only when scrolled they are loaded. i have to implement the same functionality. Any references to the realtime code will be appreciated. thanks in advance.

下面是我的code其中我得到的记录

Here is my code where i am getting the records

@foreach (System.Data.DataRow row in Model.dtSearch.Rows)
{
if (Model.dtSearch.Rows.Count > 0)
    {
    <input type ="hidden" value="@row["ProductId"]" />
    <input type ="hidden" value="@row["ProductPriceId"]" />

    <div class="divSearchResult" id="divSearch">
    <table>
    <tbody>
    <tr><td rowspan="2" style="width:10%"> @Html.Raw(row["ThumbnailFilename"])</td>
    <td colspan="3"><div class="divSearchHeader"> @row["ProductName"] <br /></div></td></tr>
    <tr><td colspan="4"><div class="divSearchShowHide" ><a class="classShow" id="show" href="#" style="text-decoration:none">Show</a></div>
    <div style="display:none;" class="divSearchContent" id=divresult_@ProductDescription > @Html.Raw(row["ProductDescription"])</div></td></tr>
    </tbody>
    </table>
    <hr />
</div>

    }}

有一个在显示code没有意义的,但是这是我必须得到的功能来实现

There is no point in showing the code but this is where i must get the functionality implemented

推荐答案

RustyLazyLoad由六个主要部分组成:

RustyLazyLoad consists of six main components:

1.rustylazyload.js 2.rustylazyload.css 3.RustyLazyLoadViewModel.cs 4._RustyLazyLoad.cshtml 5.Your控制器延迟加载操作方法和相应的视图模型 6.Your PartialView模板

1.rustylazyload.js 2.rustylazyload.css 3.RustyLazyLoadViewModel.cs 4._RustyLazyLoad.cshtml 5.Your Controller lazy load action method and the corresponding ViewModel 6.Your PartialView template

首先,我们将很快通过rustylazyload.js运行:

First, we'll quickly run through rustylazyload.js:

function LazyLoad(uniqueId) {

var _uniqueId = uniqueId;

var _containerId = "";
var _ajaxLoadContainerId = "";
var _ajaxActionUrl = "";
var _parameters = {};

this.init = function(option) {

    _containerId = option.containerId;
    _ajaxLoadContainerId = option.ajaxLoadContainerId;
    _ajaxActionUrl = option.ajaxActionUrl;
    _parameters = option.parameters;

    // Enable scroll event handler
    bindScrollHandler();

    // Load initial items
    load();
};

var bindScrollHandler = function() {
    $(window).scroll(function() {
        if ($(window).scrollTop() + $(window).height() > $(document).height() - 200) {
            load();
        }
    });
};

var unbindScrollHandler = function() {
    $(window).unbind("scroll");
};

var load = function() {
    $.ajax({
        type: "POST",
        url: _ajaxActionUrl,
        data: _parameters,
        beforeSend: load_beforeSend,
        success: load_success,
        error: load_error
    });
};

var load_beforeSend = function() {
    // Disable scroll event handler
    unbindScrollHandler();

    // Show loading message
    $(_ajaxLoadContainerId).toggleClass("lazyload-hidden").html("Loading..");
};
var load_success = function(result) {

    // Delay a bit before displaying the result and re-enabling scroll event handler
    setTimeout(function() {
        // Display result with fade in effect
        if (result != null && result != "") {
            $(_containerId).append(result, { duration: 500 });
            // Add ui-first-child to the first child
            $(_containerId).find(">:first-child").removeClass("ui-first-child");
            $(_containerId).find(">:first-child").addClass("ui-first-child");
            // Remove ui-last-child from the old last child
            $(_containerId).find(">:nth-child(" + _parameters.fromRowNumber + ")").removeClass("ui-last-child");
            // Add ui-last-child to the new last child
            $(_containerId).find(">:last-child").addClass("ui-last-child");

            // Update fromRowNumber
            _parameters.fromRowNumber = $(_containerId).children().length;
        }

        if (_parameters.fromRowNumber == 0) {
            // Use loading container to display 'no item' message
            $(_ajaxLoadContainerId).html("There is no data to display");
        } else {
            // Remove loading message
            $(_ajaxLoadContainerId).toggleClass("lazyload-hidden").html("");
        }

        // Re-enable scroll handler
        bindScrollHandler();
    }, 500);

};
var load_error = function(result) {
    var message = result.responseText.substring(1, result.responseText.length - 2);
    $(_ajaxLoadContainerId).html("Error: " + message);
};
} 

有4必填字段,我们需要指定调用的init()时:

There are 4 mandatory fields that we need to specify when calling init():

_containerId - 数据容器对象的ID(&LT; UL ID =thisId&GT;&LT; / UL&GT; ) _ajaxLoadContainerId - 加载消息容器对象的ID(&LT; D​​IV ID =thisId&GT;中..&LT; / DIV&GT; ) _ajaxActionUrl - 操作URL将使用$就被称为() _parameters - 一个JSON对象,其中有2个必填字段:限制(项目数量将根据需要加载)和fromRowNumber(标志着第N加载项,以避免重复的条目)

_containerId - the Id of the data container object (<ul id="thisId"></ul>) _ajaxLoadContainerId - the Id of the "Loading" message container object (<div id="thisId">Loading..</div>) _ajaxActionUrl - The action Url which will be called using $.ajax() _parameters - a JSON object, which has 2 mandatory fields: limit (number of items to be loaded on demand) and fromRowNumber (marks the Nth loaded item to avoid repeated entries).

我们不会去讨论上面的一行行此code,相反,我们将只突出重要的部分:

We won't go and discuss this code above line by line, instead we'll just highlight the important sections:

init()函数做了三件事:进行参数映射,滚动事件处理程序绑定到窗口,并调用load()来显示第一批 bindScrollHandler()是非常微不足道的 - 它只是确保负载()被调用时,窗口几乎到达底部

init() function does three things: maps the parameters, binds scroll event handler to the window, and calls load() to display the first batch bindScrollHandler() is quite trivial - it simply makes sure load() gets called when the window almost reaches the bottom

load()的调用_ajaxActionUrl使用jQuery AJAX和传入_parameters所有指定的参数变量 - ASP.NET MVC是足够聪明的映射这些参数与控制器的操作参数

load() calls _ajaxActionUrl using jQuery AJAX and passes all specified parameters in _parameters variable - ASP.NET MVC is smart enough to map those parameters with the Controller action parameters

在控制器的动作执行, load_beforeSend()暂时禁止窗口滚动的事件处理程序,所以我们不超载的服务器AJAX请求,同时会显示加载信息该ID存储在_ajaxLoadContainerId HTML对象 如果成功, load_success()要绑定的结果_containerId HTML对象,更新 _parameters.fromRowNumber 与数量项目加载(还记得fromRowNumber是_parameters的强制性项目之一),并重新启用窗口滚动事件处理程序 任何错误将在load_error(),这将显示在_ajaxLoadContainerId HTML对象来处理

When the Controller action is performing, load_beforeSend() temporarily disables the window scroll event handler so we don't overload the server with AJAX requests, meanwhile displays the loading message HTML object which Id is stored in _ajaxLoadContainerId On success, load_success() should bind the result to _containerId HTML object, update the _parameters.fromRowNumber with the number of items loaded (remember fromRowNumber is one of the mandatory items of _parameters), and re-enables the window scroll event handler Any error will be handled in load_error(), which will be displayed in _ajaxLoadContainerId HTML object

如果您使用的是默认的ASP.NET MVC4移动应用模板,你不需要在所有修改此文件

If you are using default ASP.NET MVC4 Mobile Application template, you shouldn't need to modify this file at all

接下来是rustylazyload.css,这应该是很简单的:

Next is rustylazyload.css, which should be quite straight forward:

.lazyload-loading-container {
margin: 0;
padding: 15px;
text-align: center;
}
.lazyload-hidden {
display: none;
 }

现在,视图模型RustyLazyLoadViewModel.cs:

Now, the View Model RustyLazyLoadViewModel.cs:

  using System.Collections.Generic;

  namespace RustyLazyLoadTester.Mobile.Models
  {
public class RustyLazyLoadViewModel
{
    public RustyLazyLoadViewModel()
    {
        Parameters = new Dictionary<string, object>();
    }
    public RustyLazyLoadViewModel(int limit, int fromRowNumber, string containerId,
        string ajaxActionUrl, IDictionary<string, object> parameters = null)
    {
        Limit = limit;
        FromRowNumber = fromRowNumber;
        ContainerId = containerId;
        AjaxActionUrl = ajaxActionUrl;
        if (parameters != null)
            Parameters = parameters;
    }

    public int Limit { get; set; }
    public int FromRowNumber { get; set; }
    public string ContainerId { get; set; }
    public string AjaxActionUrl { get; set; }
    public IDictionary<string, object> Parameters { get; set; }
}
}

正如你所看到的,这个视图模型捕捉pretty的大致相同参数rustylazyload.js .init()的功能,除了没有_ajaxLoadContainerId。为什么?让我们来看看视图文件。

As you can see, this View Model captures pretty much the same parameters as rustylazyload.js' .init() function, except without the _ajaxLoadContainerId. Why? Let's check out the View file.

_RustyLazyLoad.cshtml:

 @using System.Text
 @model RustyLazyLoadTester.Mobile.Models.RustyLazyLoadViewModel
 @{
var containerId = Model.ContainerId;
var ajaxLoadContainerId = string.Format("{0}Load", containerId);

// Convert parameters to JSON
var sbParameters = new StringBuilder();
if (Model.Parameters != null && Model.Parameters.Any())
{
    foreach (var parameter in Model.Parameters)
    {
        sbParameters.AppendFormat("\"{0}\": \"{1}\", ", parameter.Key, parameter.Value);
    }
}
var parameters = sbParameters.ToString();
// Remove trailing ', ' from parameters
if (!string.IsNullOrWhiteSpace(parameters))
{
    parameters = parameters.Substring(0, parameters.Length - 2);
}
}
<ul id="@containerId" data-role="listview" 
         data-inset="true"></ul>
<div id="@ajaxLoadContainerId"
 class="lazyload-loading-container lazyload-hidden
        ui-listview ui-listview-inset
        ui-corner-all ui-shadow ui-li-static
        ui-btn-down-b ui-first-child ui-last-child"></div>
<script type="text/javascript">
$(document).ready(function () {
    var limit = @Model.Limit;
    var fromRowNumber = @Model.FromRowNumber;
    var containerId = '@string.Format("#{0}", containerId)';
    var ajaxLoadContainerId = '@string.Format("#{0}", ajaxLoadContainerId)';
    var ajaxActionUrl = '@Model.AjaxActionUrl';
    var parameters = { limit: limit, fromRowNumber: fromRowNumber, @Html.Raw(parameters) };

    var lazyLoad = new LazyLoad(containerId);
    lazyLoad.init({
        containerId: containerId,
        ajaxLoadContainerId: ajaxLoadContainerId,
        ajaxActionUrl: ajaxActionUrl,
        parameters: parameters
    });
});
</script>

为了简单起见,_ajaxLoadContainerId其实只是_containerId带有后缀,但它可以是任何东西,真的。如果我们觉得需要手动指定您的AJAX加载消息容器ID,我们需要做的就是在RustyLazyLoadViewModel.cs添加AjaxLoadContainerId作为属性,并传递到变量ajaxLoadContainerId(在本页面5线)。

For simplicity, _ajaxLoadContainerId is really just _containerId with a suffix, but it can be anything, really. Should we feel the need to specify your AJAX loading message container Id manually, all we need to do is add AjaxLoadContainerId as a property in RustyLazyLoadViewModel.cs and pass that on to variable ajaxLoadContainerId (line 5 in this page).

延迟加载项容器是这样的:

 <ul id="@containerId" data-role="listview" data-inset="true"></ul> 

和延迟加载加载消息容器是这样的:

And the lazy load loading message container is this:

 <div id="@ajaxLoadContainerId" ...></div>  

然后用剃刀引擎我们转换参数为JSON并将其传递给懒惰的负荷控制。

Then using the Razor engine we convert the parameters into a JSON and pass it on to the lazy load control.

var parameters = { limit: limit, fromRowNumber: fromRowNumber, @Html.Raw(parameters) };

var lazyLoad = new LazyLoad(containerId);
lazyLoad.init({
containerId: containerId,
ajaxLoadContainerId: ajaxLoadContainerId,
ajaxActionUrl: ajaxActionUrl,
parameters: parameters
}); 

最后,第五和第六元件最好通过一个例子来说明。

Lastly, the fifth and sixth component are best explained through an example.

说,有网友在这些领域的数据库15项:编号,名字,姓氏,状态并映射到下面的模型。我们希望通过延迟加载控制以渐进的方式显示在主页上的条目。

Say there are 15 entries of User in the database with these fields: Id, FirstName, LastName, Status and mapped to the model below. and we want to display the entries on the Home page in a progressive manner using the lazy load control.

 using System.ComponentModel;

 namespace RustyLazyLoadTester.Mobile.Services.Models
 {
public class User
{
    public User() { }
    public User(long id, string firstName, string lastName, UserStatus status)
        : this()
    {
        Id = id;
        FirstName = firstName;
        LastName = lastName;
        Status = status;
    }

    public long Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public UserStatus Status { get; set; }
}

public enum UserStatus
{
    [Description("All")]
    All = 0,
    [Description("Inactive")]
    Inactive = 1,
    [Description("Active")]
    Active = 2,
    [Description("Deactivated")]
    Deactivated = 3
}
}

我们需要做的第一件事是创建服务方法:

using System.Collections.Generic;
using System.Linq;
using RustyLazyLoadTester.Mobile.Services.Models;

namespace RustyLazyLoadTester.Mobile.Services
{
public interface IQueryService
{
    IEnumerable<User> GetAllUsers(UserStatus status = UserStatus.All,
                                  int limit = 0, int fromRowNumber = 0);
}

class QueryService : IQueryService
{
    public IEnumerable<User> GetAllUsers(UserStatus status, int limit, int fromRowNumber)
    {
        // Assume we have 15 users
        var users = new List<User>();
        for (var i = 0; i < 15; i++)
        {
            var userFirstName = string.Format("firstName_{0}", i);
            var userLastName = string.Format("lastName_{0}", i);
            var userStatus = i % 2 == 0 ? UserStatus.Active : UserStatus.Inactive;
            users.Add(new User(i, userFirstName, userLastName, userStatus));
        }

        if (limit <= 0)
        {
            users = users.Where(x => x.Status == status)
                        .Skip(fromRowNumber)
                        .ToList();
        }
        else
        {
            users = users.Where(x => x.Status == status)
                        .Skip(fromRowNumber)
                        .Take(limit)
                        .ToList();
        }
        return users;
    }
}
}

在我们的HomeController中,我们需要创建默认的[HTTPGET]控制器的操作方法指数()为我们的索引页和[HttpPost]控制器的操作方法GetNextUsers()来服务延迟加载器:

In our HomeController, we will need to create the default [HttpGet] Controller action method Index() for our Index page and the [HttpPost] Controller action method GetNextUsers() to serve the lazy loader:

using System;
using System.Linq;
using System.Net;
using System.Web.Mvc;
using RustyLazyLoadTester.Mobile.Services;
using RustyLazyLoadTester.Mobile.Services.Models;

namespace RustyLazyLoadTester.Mobile.Controllers
{
public class HomeController : Controller
{
    private readonly IQueryService _query;

    public HomeController()
    {
        _query = new QueryService();
    }

    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult GetNextUsers(UserStatus status, int limit, int fromRowNumber)
    {
        try
        {
            var users = _query.GetAllUsers(status, limit, fromRowNumber);

            if (!users.Any())
                return Json(string.Empty);

            return PartialView("_UserList", users);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            return Json(ex.Message);
        }
    }
}
}

在Index.cshtml(对应于查看[HTTPGET]控制器的操作方法指数()),我们会是这样的:

In Index.cshtml (the View corresponding to the [HttpGet] Controller action method Index()) we will have something like this:

@using RustyLazyLoadTester
@using RustyLazyLoadTester.Mobile.Models
@using RustyLazyLoadTester.Mobile.Services.Models
@{
ViewBag.PageTitle = "Home";
ViewBag.Title = string.Format("RustyLazyLoadTester - {0}", ViewBag.PageTitle);

var parameters = new Dictionary<string, object>();
parameters.Add("status", UserStatus.All);
}
@Scripts.Render("~/bundles/lazyload") @* points to /Scripts/rustylazyload.js *@

@Html.Partial("_RustyLazyLoad", new RustyLazyLoadViewModel(
5, 0, "ulUsers", Url.Action("GetNextUsers", "Home"), parameters))

这两个粗线会激活延迟加载控制和触发GetNextUsers()上的需求。

The two bolded lines there will activate the lazy load control and trigger the GetNextUsers() on demand.

如果我们仔细观察第二粗体行:

If we look closely on the second bolded line:

@Html.Partial("_RustyLazyLoad", new RustyLazyLoadViewModel(
5, 0, "ulUsers", Url.Action("GetNextUsers", "Home"), parameters)) 

值5是极限。这规定了如何检索每个负载的项目数。值0是fromRowNumber。这种再presents第N项中需要被忽略的结果。当我们加载更多的数据,这一数字将增加基础上,加载的项目,所以我们不必担心重复的(除非我们code涉及到一些复杂的排序,这使得它可能在中间的一个新项目列表)。

The value 5 is the limit. This dictates how the number of items to be retrieved on each load. The value 0 is the fromRowNumber. This represents the N-th item in the result that needs to be ignored. As we load more data, this number will increase based on the loaded items, so we don't have to worry about duplicates (unless our code involves some complex sorting which makes it possible to have a new item in the middle of the list).

在GetNextUsers()方法被调用,它只是呈现PartialView _UserList.cshtml如下:

When GetNextUsers() method is called, it simply renders PartialView _UserList.cshtml below:

@using Humanizer
@using RustyLazyLoadTester.Mobile.Services.Models
@model IEnumerable<User>

@foreach (var user in Model)
{ 
<li class="ui-li ui-li-static ui-btn-up-b">
    <div>@string.Format("First name: {0}", user.FirstName)</div>
    <div>@string.Format("Last name: {0}", user.LastName)</div>
    <div>@string.Format("Status: {0}", user.Status.Humanize())</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
    <div>---</div>
</li>
}

请注意,该内容被包裹在一个。这样做的原因是因为父容器(_containerId HTML对象)是一个。但是,我们可以随时改变这个实现很容易,只要我们保持如下的层次:

Note that the content is wrapped in an . The reason for this is because the parent container (_containerId HTML object) is a . But we can always change this implementation very easily, as long as we maintain the hierarchy as below:

<parentContainer>
  <childContainer>
     [Content]
  </childContainer>
</parentContainer> 

这是因为RustyLazyLoad控制使用儿童的父容器的数量来更新_fromRowNumber属性,这样可以确保不会在接下来的负载没有重复的条目。

This is because RustyLazyLoad control uses the parent container's number of children to update the _fromRowNumber property, which ensures there is no duplicate entry in the next load.

以上code不是我写的。不过,我已经成功地使用在我的项目。参考取自link在这里你有完整的描述。所有学分Teddy Segoro 的。我曾经转贴它只是一个信息共享。你可以找到的工作模式为

The above code is not written by me. But i have successfully used in my project. the reference is taken from the link where you have the complete description. All credits to Teddy Segoro . I have reposted it only for an information sharing. You can find the working model as