[JS Exam] Гайд - Как всъщност се прави страницирането


8

Забелязах че почти не са се намерили хора които да са успели да направят странициране на изпита. От работите които проверих, само 1 човек беше направил нещо което наподобяваше странициране, но то се чупеше още при първия клик.
Това е жалко, защото страницирането хем е готино нещо, хем е много лесно.

Реших да пусна един малък гайд, за да обясня как съм го направил аз. Надявам се това да е полезно на всички които по-нататък ще продължат да се занимават с JavaScript.

1-ва стъпка - взимате постовете и ги преброявате. Ако постовете са масив, тогава преброяването е лесно - ползвате пропъртито length. Ако не са - намирате друг начин да ги преброите. За примера отдолу ще предположим че сме запазили броя им в променливата countOfPosts.

2-ра стъпка - взимате настройките на юзъра. Някъде, по някакъв начин, е било определено колко поста да има на страница. Ако сте го направили добре, това ще е определено от юзъра в панела за настройки. В противен случай  може да е дори от конзолата, или някакво магическо число - както и да е. Подсигурявате си че има как да вземете това число. За примера ще го пазим в променливата postsPerPage.

3-та стъпка - взимате инпута за избор на страница. Тоест - подсигурявате се че винаги в метода ще ви се подава коя страница иска да види юзъра. Лесен начин да го направите е да зададете дефоултна страница (първата), така че ако не е избрана друга да се показва тя. За примера инпута за страница ще е в променливата pageNumber.

4-та стъпка - използвате този метод за да селектирате само постовете които са на конкретната страница. Този метод всъщност е филтриращ метод. Той маха всички постове които не са на конкретната страница:

// важно: В метода се предполага че броенето на страниците започва от 1, а не от 0!

getPostsOnPage(allPosts, pageNumber, postsPerPage)
{

 var countOfPosts = allPosts.length;
var firstIndexOfPage = (pageNumber - 1) * postsPerPage;
var lastIndexOfPage = pageNumber * postsPerPage;
var postsOnPage = [];

if (lastIndexOfPage >= countOfPosts )
{
lastIndexOfPage = countOfPosts -1;
}

for (currentPost = firstIndexOfPage ; currentPost < lastIndexOfPage ; currentPost++)
{
postsOnPage.push(allPosts[currentPost])
}

return postsOnPage;
}

5-та стъпка - Визуализирате филтрираните постове. Правете го както си искате.

6-та стъпка - Визуализиране на самите страници. То става така:

countOfPages = (countOfPosts / postsPerPage) + 1;

После минавате толкова пъти през цикъл и създавате по един линк към страница за всяко минаване.

 



Страниците са илюзия. Всъщност няма никакви страници, докато не сте цъкнали на тях. Съществува само страницата която искате да видите. Останалите не са скрити, а просто ги няма.




Отговори



2

Или още по-лесно:

var paging = function(arr, size) {

  var pages = [];
 
  size = size || this.length;
 
  while (arr.length) {
    pages.push(arr.splice(0, size));
  }
 
  return pages;
};
 
Ще ти създаде масив с масиви, за всяка страница си правиш arr[page] и ще ти върне масива за страницата.
 
Ето и как работи наистина : http://jsfiddle.net/85T7n/2/

от penjurov (1466 точки)


0
Да, това наистина е по-просто. Но защо са ти всички тези страници, щом показваш само една?
Ако смесим 2-та примера ще се получи нещо дори по-елементарно. Слайсването ще е само 1 и само за текущата страница. (според мен другите страници не ти трябват. Защо? Защото когато юзъра цъкне да отиде на друга страница се очаква да има и рефреш на всички постове (тоест ако има нови постове страниците ще се изместят настрани. Така е в повечето сайтове). По тази причина е излишно да се режат всичките парчета. Трябва ти само текущото.)
Всъщност, май е едно и също. Сплайс с тея аргументи надали прави нещо по-различно от написаното горе. Разликата е че променя и самия масив подаден в аргументите, което в някои ситуации може да изиграе лоша шега. Бих предпочел метода slice(), или някой друг който да върши същото нещо.

от lokiko91 (790 точки)

0
Това не са страници, а масив :) Вече показвай каквото искаш. Така или иначе и в твоето решение има AllPosts, нали? Дали ще пазиш всички данни в един масив или в масив в масиви каква е разликата :) А и по този начин всичко го правиш веднъж в началото(като зареждаш търсенето), а не всеки път да въртиш по N на брой пъти.

от penjurov (1466 точки)



0

Проблема е в трета стъпка - какво да покажеш на потребителя като интерфейс за избиране на страница. Дали да му покажеш линкове/бутони Next/Previous, дали да му изредиш всички номера на страници за да може да клика на тях. Какво става ако има само една страница. Какво става ако има 100 страници - колко линка с номера ще се виждат, ще се превъртат ли, как ще се стилизира номера на активната страница... Дори да е само с Next/Previous  - кога са активни, какво става като стигнеш на края? Ако е така, потребителя ще вижда ли поне номера на страницата на която е и къде? Както се казва, the devil is in the details ;)


от neutrino (3376 точки)


0
Е аз за това ползвах Kendo Grid :) Попитах трейнърите ОК ли е, вдигнаха рамене, реших че е :) После във видеото Дончо каза, че не било :P Дали не ми стана тъпо :D

от penjurov (1466 точки)

0
Това не е четвърта, а шеста стъпка. То се прави отделно. Аз лично го направих с показване на всички линкове, но всъщност няма нищо по-лесно от това да покажеш само няколко.
Добра идея например е да покажеш само първия, последния и 11 линка в средата (5 преди текущия, самият текущ и 5 след него). Или пък да не са 11, а друго нечетно число...
Това вече е въпрос на дизайн. Както и да го направиш - алгоритъма си е същия.

от lokiko91 (790 точки)



0
Като правите пейджиране, дърпайте само данните, които ви трябват.Това allPosts, не е добра идея, щото постовете може да са милион и нагоре.Особоено пък ако пейджирането е на клиентската част.



0
За целта трябва на сървъра да има такава възможност. На изпита нямаше.

от lokiko91 (790 точки)

0
Ок.Попринцип го казвам :)



2

Ето и моето решение от изпита с помощта на uderscore.js

            function showData(post) {
                var postToShow = post,
                    postPerPage = $('#post-per-page').val();
 
                if (postPerPage) {
                    postToShow = _.first(postToShow, postPerPage * currentPage);
                    postToShow = _.last(postToShow, postPerPage);
                }
 
                uiShow.Post(postToShow);
            }
 
Тук currentPage е променлива, която съм взел от потребителя малко по-нагоре в кода, а postToShow е масив от постове - филтрирани както е пожелал потребителя :)

от wnvko (3123 точки)