Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
565 views
in Technique[技术] by (71.8m points)

For loop not returning expected value - C# - Blazor

Using Blazor, I am creating a pagination feature for my project. The main concept is just using linq's .Skip() and .Take(), I will only take the list items for the page clicked from the list.

The code that creates the pagination buttons: (E.G: 1,2,3)

<ul class="pagination float-center">
  @for (int i = 0; i < Math.Ceiling((decimal)articleService.ReturnAll().Count() / numPerPage); i++)
    {
      <li class="page-item"><a class="page-link" onclick="@(() => ReturnPage(i))">@i</a></li>
    }
</ul>

I'm fine withing using 0 indexing here for my pagination.

This above code creates the buttons that when pressed (say page 1 which is the 2nd page), passes the index of the for loop which I will later multiply by the amount per page, to get the amount of elements in the list to skip.

For example when clicking page 1, I will need to skip 2 elements in the list, then take the next 2. (Assuming I want 2 items as the amount per page)

Then my ReturnPage function will skip the current page (whats clicked) - 1, then multiply by 2 (or amount per page) to find the total amount to skip. If the user clicks 0 (first page) then I need to .Skip(0) and just .Take(amount per page).

void ReturnPage(int i)
 {

    articles = articleService.ReturnAll()
                                .OrderByDescending(x => x.LastUpdated)
                                    .Skip((i == 0) ? 0 : (i - 1) == 0 ? numPerPage : (i - 1) * numPerPage)
                                        .Take(numPerPage)
                                            .ToList();
 }

Putting this into context if I have a list (articles) with a total count of items at 3. This will return me pagination buttons of 0,1. page 0 will show 2 items, and page 1 will show 1 item.

If I click pagination button 1, I should pass 1 (i) to the ReturnPage method and that will calculate a skip amount of 2 items. Meaning this page will skip the first 2 items in the list, then take the next 2. (just 1 item in this case)

If I click back to pagination button 0, I should pass an i value of 0, skipping nothing, and just take the first 2 items.

However I am not seeing the correct (i) value being passed into the ReturnPage function at all.

Running the same example I outlined above, the correct amount of buttons are returned by the for loop: Pagination Buttons

But when debugging, i has a value of 2 (everytime?). Which throws off the whole .Skip() functionality.

Wrong Expected Value

My interpretation is, completely disregarding the linq stuff, something in the for loop is wrong. The condition seems correct to me. If I have a count of 3 and 2 per page, which is 1.5 which would mean 2 pages. So my i values should be 0 and 1, but somehow its 2?

I must be missing something fundamental here, any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your for loop should contain a local variable like this:

 @for (int i = 0; i < Math.Ceiling((decimal)articleService.ReturnAll().Count() / numPerPage); i++)
    {
       var localVariable = i;

      <li class="page-item"><a class="page-link" onclick="@(() => ReturnPage(localVariable ))">@i</a></li>
    }

This is standard C# behavior where lambda expression @(() => ReturnPage(localVariable )) has access to a variable and not to the value of the variable. You have to define a variable which is local to the for loop, otherwise your lambda expression will always call ReturnPage(i) and i equals Math.Ceiling((decimal)articleService.ReturnAll().Count() at the end of the loop.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...