C# 仅当页面向下滚动MVC4jQuery Mobile时加载数据
在我看来,我正在填充从一个有1000多条记录的表中提取的内容。我必须以这样一种方式填充内容:只有向下滚动时,记录才会被填充到更少的记录中,而不是一次填充。我使用它来开发移动应用程序。我尝试过各种在线资源,但没有达到滚动的效果。如果你们仍然不清楚我的问题,你们中的大多数人可能已经使用了facebook。在那里,没有一次加载所有的帖子。只有在滚动时才会加载它们。我必须实现相同的功能。任何对实时代码的引用都将不胜感激。提前谢谢 这是我获取记录的代码C# 仅当页面向下滚动MVC4jQuery Mobile时加载数据,c#,asp.net,ajax,asp.net-mvc-4,jquery-mobile,C#,Asp.net,Ajax,Asp.net Mvc 4,Jquery Mobile,在我看来,我正在填充从一个有1000多条记录的表中提取的内容。我必须以这样一种方式填充内容:只有向下滚动时,记录才会被填充到更少的记录中,而不是一次填充。我使用它来开发移动应用程序。我尝试过各种在线资源,但没有达到滚动的效果。如果你们仍然不清楚我的问题,你们中的大多数人可能已经使用了facebook。在那里,没有一次加载所有的帖子。只有在滚动时才会加载它们。我必须实现相同的功能。任何对实时代码的引用都将不胜感激。提前谢谢 这是我获取记录的代码 @foreach (System.Data.Data
@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>
}}
@foreach(Model.dtSearch.Rows中的System.Data.DataRow行)
{
如果(Model.dtSearch.Rows.Count>0)
{
@Html.Raw(行[“ThumbnailFilename”])
@行[“ProductName”]
@Html.Raw(第[“ProductDescription”]行)
}}
显示代码没有意义,但这是我必须实现功能的地方我还没有尝试过这一点,但很快就会找到类似的解决方案:术语称为“延迟加载”
铁锈负载由六个主要部件组成: 1.rustylazyload.js
2.rustylazyload.css
3.RustyLazyLoadViewModel.cs
4._RustyLazyLoad.cshtml
5.您的控制器延迟加载操作方法和相应的ViewModel
6.您的PartialView模板 首先,我们将快速运行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);
};
}
调用init()时需要指定4个必填字段:
_containerId—数据容器对象的Id(
)_ajaxLoadContainerId—“正在加载”消息容器对象的Id(
load..
)_ajaxActionUrl—将使用$.ajax()调用的操作Url
_parameters—一个JSON对象,它有两个必填字段:limit(按需加载的项目数)和fromRowNumber(标记第n个加载的项目以避免重复输入) 我们不会逐行讨论这段代码,我们只会强调以下重要部分: init()函数做三件事:映射参数,将scroll事件处理程序绑定到窗口,并调用load()以显示第一批
bindScrollHandler()非常简单-它只是确保在窗口几乎到达底部时调用load() load()使用jQuery AJAX调用_ajaxActionUrl,并在_parameters变量中传递所有指定的参数-ASP.NET MVC足够聪明,可以将这些参数与控制器操作参数映射 执行控制器操作时,
load\u beforeSend()
临时禁用窗口滚动事件处理程序,这样我们就不会用AJAX请求重载服务器,同时显示加载消息HTML对象,该对象的Id存储在_ajaxLoadContainerId中
成功时,load_success()
应将结果绑定到_containerIDHTML对象,用加载的项目数更新\u参数。fromRowNumber
(记住fromRowNumber是_参数的必需项之一),并重新启用窗口滚动事件处理程序
任何错误都将在load_error()中处理,该错误将显示在_ajaxLoadContainerIdHTML对象中
如果您使用的是默认的ASP.NET MVC4移动应用程序模板,则根本不需要修改此文件
接下来是rustylazyload.css,它应该非常简单:
.lazyload-loading-container {
margin: 0;
padding: 15px;
text-align: center;
}
.lazyload-hidden {
display: none;
}
现在,视图模型将显示在LoadViewModel.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; }
}
}
为简单起见,ajaxLoadContainerId实际上只是带有后缀的containerId,但它可以是任何东西,真的。如果我们觉得有必要手动指定AJAX加载消息容器Id,我们只需将AjaxLoadContainerId作为属性添加到rustylazLoadViewModel.cs中,并将其传递给变量AjaxLoadContainerId(本页第5行)
延迟加载项容器如下所示:
@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>
<ul id="@containerId" data-role="listview" data-inset="true"></ul>
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;
}
}
}
最后,通过一个例子对第五和第六部分进行了最好的解释
假设数据库中有15个用户条目,其中包含以下字段:Id、FirstName、LastName、Status和mapped to the model。我们希望使用惰性负载控制以渐进的方式在主页上显示条目
var parameters = { limit: limit, fromRowNumber: fromRowNumber, @Html.Raw(parameters) };
var lazyLoad = new LazyLoad(containerId);
lazyLoad.init({
containerId: containerId,
ajaxLoadContainerId: ajaxLoadContainerId,
ajaxActionUrl: ajaxActionUrl,
parameters: parameters
});
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.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>
<ul id="@containerId" data-role="listview" data-inset="true"></ul>
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;
}
}
}
在Index.cshtml(对应于[HttpGet]控制器操作方法Index()的视图)中,我们将有如下内容:
@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))
值5是极限。这说明了如何在每次加载时检索项目数。值0是fromRowNumber。这表示结果中需要忽略的第N项。当我们加载更多的数据时,这个数字将根据加载的项目而增加,所以我们不必担心重复(除非我们的代码涉及到一些复杂的排序,这使得在列表中间有一个新的项目)。
调用GetNextUsers()方法时,它只会在下面呈现PartialView\u UserList.cshtml:
@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>
}
@使用人性化工具
@使用RustyLazyLoadTester.Mobile.Services.Models
@模型IEnumerable
@foreach(模型中的var用户)
{
@格式(“名字:{0}”,user.FirstName)
@格式(“姓氏:{0}”,user.LastName)
@Format(“状态:{0}”,user.Status.Humanize())
---
---
---
---
---
---
---
---
---
---
---
---
---
---
}
请注意,内容包装在<parentContainer>
<childContainer>
[Content]
</childContainer>
</parentContainer>
[内容]
这是因为RustyLazyLoad控件使用父容器的子容器数来更新