我正在努力解决这个问题,但是我一辈子都做不到!
我正在调用一个分页的API,每个页面有20个项目。我正在尝试在UI上实现无限滚动以使用此API中的数据,并且一次加载12个项目,因此我需要确定我需要从哪个页码中获取该API中要包含的页数。 / p>
例如:
我目前在第10项上,我想再增加20项,这意味着我需要从第1页中拿出10项,然后从第2页中拿出10项。但是我不知道该怎么做!
这是我正在使用的模型:
public class PagesToLoad
{
public int Page { get; set; }
public int Take { get; set; }
public int Skip { get; set; }
}
这是方法签名
public static List<PagesToLoad> GetPage(int currentlyLoaded, int toLoad, int maxItemsPerPage)
我将向您展示我已经尝试过的方法,但是这毫无意义,因为我无法确定该怎么做。
一些例子:
currentlyLoaded = 0,我想加载12,而maxItemsPerPage
是20。
因此结果应为:
new List<PagesToLoad>
{
new PagesToLoad
{
Page = 1,
Skip = 0,
Take = 12
},
}
currentlyLoaded = 10,我想加载20,而maxItemsPerPage
是20。
所以结果应该是:
new List<PagesToLoad>
{
new PagesToLoad
{
Page = 1,
Skip = 10,
Take = 10
},
new PagesToLoad
{
Page = 2,
Take = 10,
Skip = 0
}
}
更新:
我已经编写了一些单元测试,以尝试使用NUnit测试其中一些场景。 下面的测试仅当前测试它是否返回了我们应该从中获取的正确页面,并且当前未测试当前页面上的正确位置
[TestCaseSource(nameof(TestData))]
public void TestPaginationPagesToLoad(int currentlyLoaded, int toLoad, int maxItemsPerPage, int[] expectedPages)
{
var result = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, maxItemsPerPage);
var pages = result.Select(x => x.Page).ToArray();
Assert.That(pages.Length, Is.EqualTo(expectedPages.Length), "Did not contain the correct amount of pages");
for (int i = 0; i < pages.Length; i++)
{
Assert.That(pages[i], Is.EqualTo(expectedPages[i]));
}
}
public static IEnumerable<TestCaseData> TestData
{
get
{
yield return new TestCaseData(0, 10, 20, new [] { 1 }).SetName("Load_First_Page");
yield return new TestCaseData(20, 10, 20, new [] { 2 }).SetName("Load_Second_Page");
yield return new TestCaseData(0, 20, 20, new [] { 1 }).SetName("Load_Full_First_Page");
yield return new TestCaseData(20, 20, 20, new [] { 2 }).SetName("Load_Full_Second_Page");
yield return new TestCaseData(10, 20, 20, new [] { 1, 2 }).SetName("Load_Half_First_Page_And_Half_Second_Page");
yield return new TestCaseData(19, 20, 20, new [] { 1, 2 }).SetName("Load_End_First_Page_And_Most_Second_Page");
}
}
答案 0 :(得分:2)
第n页包含从(sn-s + 1)到sn的项目,两端都包括在内,其中s是每页的项目数。假设您在项目m处,并且想再购买k个项目。然后,您要取m + 1,m + 2,...,m + k。您需要查看的第一页是(m +1-1)/ s +1,其中除法是整数除法(只是商,无余数)。在该页面上,您需要从(m +1-1)%s +1开始计算,其中%是除(模数)后的余数。您需要查看的最后一页是(m + k-1)/ s +1,并且您最多需要查看(m + k-1)%s + 1。
您的示例:
s = 20
m = 10
k = 20
first page: (m + 1 - 1) / s + 1
= (10 + 1 - 1) / 20 + 1
= 10 / 20 + 1
= 0 + 1 = 1
start pos: (m + 1 - 1) % s + 1
= (10 + 1 - 1) % 20 + 1
= 10 % 20 + 1
= 10 + 1 = 11
last page: (m + k - 1) / s + 1
= (10 + 20 - 1) / 20 + 1
= 29/20 + 1
= 1 + 1 = 2
stop pos: (m + k - 1) % s + 1
= (10 + 20 - 1) % 20 + 1
= 29 % 20 + 1
= 9 + 1 = 10
请注意,如果使用last page > first page + 1
,则需要获取它们之间的整个页面。
编辑:添加一些C#,甚至可以工作!
List<PagesToLoad> GetPagesToload(int curItemIndex, int numItemsToGet, int itemsPerPage)
{
List<PagesToLoad> result = new List<pagesToLoad>();
int firstPage = curItemIndex / itemsPerPage + 1;
int startPos = curItemIndex % itemsPerPage + 1;
int lastItemIndex = curItemIndex + numItemsToGet - 1;
int lastPage = lastItemIndex / itemsPerPage + 1;
int stopPos = lastItemIndex % itemsPerPage + 1;
PagesToLoad page1 = new PagesToLoad();
page1.Page = firstPage;
page1.Skip = curItemIndex;
page1.Take = numItemsToGet;
if (numItemsToGet + startPos - 1 > itemsPerPage)
{
page1.Take = itemsPerPage - startPos + 1;
result.Add(page1);
for (int i = firstPage + 1; i < lastPage; i++)
{
PagesToAdd nextPage = new PagesToAdd();
nextPage.Page = i;
nextPage.Skip = 0;
nextPage.Take = itemsPerPage;
result.Add(nextPage);
}
PagesToAdd pageN = new PagesToAdd();
pageN.Page = lastPage;
pageN.Skip = 0;
pageN.Take = stopPos;
result.Add(pageN);
}
else
{
result.Add(page1);
}
return result;
}
我没有测试该代码,甚至没有尝试对其进行编译-但这可能会让您有足够的主意以使其正确使用。