Я хотел бы изменить ярлыки страниц в Yii.
Я использовал Zii.widegt.CListView
чтобы отобразить список элементов. По умолчанию структура разбиения на страницы yii [previous] 1 2 4 5 6 7 [next]
требуемая структура < 1....10 11 12 13 14 ....40 >
.
Я прочитал « Как настроить ярлыки для пейджера в Yii? », Что полезно, но как я могу показать firstPageLabel
как номер страницы 1 вместо <<
и lastPageLabel
как 40 вместо >>
.
Если вы не можете найти способ передать общее количество элементов (например, 40) в переопределение lastPageLabel
, вам необходимо переопределить класс CLinkPager, чтобы эта работа выполнялась автоматически. $ LastPageLabel статичен в текущей реализации и не предоставляет доступ к переменным типа "itemCount". Вы можете увидеть код:
$buttons[]=$this->createPageButton($this->lastPageLabel,$pageCount-1,self::CSS_LAST_PAGE,$currentPage>=$pageCount-1,false);
Это просто echos $this->lastPageLabel
, который является статическим текстом.
Если вы создадите новый пейджер (называемый, скажем, MyLinkPager), используйте его так:
$this->widget('zii.widgets.CListView', array( 'dataProvider' => $categoryProjects, 'itemView' => '_itemDetailsView', 'ajaxUpdate' => false, 'pager' => array( 'class' => 'MyLinkPager', // here is your pager 'firstPageLabel' => '<<', 'prevPageLabel' => '<', 'nextPageLabel' => '>', 'lastPageLabel' => '>>', ), ));
Вам нужно будет создать свой собственный класс, который происходит от CLinkPager
. В конечном счете, вы хотите изменить линию, о которой упоминает thaddeusmt , внутри CLinkPager::createPageButtons
:
$buttons[]=$this->createPageButton($this->lastPageLabel /* the rest doesn't matter */);
сделать эквивалент
$buttons[]=$this->createPageButton($pageCount /* the rest doesn't matter */);
Теперь очевидно, что прямой способ сделать это – переопределить createPageButtons
, но это не тривиальный метод, и если вы полностью переопределите его, вы рискуете своим пейджером «не синхронизироваться» с кодом в более поздних версиях Yii. Итак, давайте искать альтернативы.
(вы можете пропустить эту часть, если вас интересует только решение)
Один из вариантов – переопределить метод, вызвать стандартную реализацию и просто изменить то, что вам нужно изменить:
protected function createPageButtons() { $buttons = parent::createPageButtons(); // Yii's implementation array_pop($buttons); // remove last item, which is the link for the last page $buttons[]=$this->createPageButton($this->getPageCount() /* the rest unchanged */); return $buttons; }
Это лучше, но по-прежнему требуется копирование / вставка кода, поэтому ваша реализация должна синхронизировать эту часть с будущими версиями Yii. Мы можем сделать лучше? Получается, что да. Вот метод CLinkPager::run
:
public function run() { $this->registerClientScript(); $buttons=$this->createPageButtons(); if(empty($buttons)) return; echo $this->header; echo CHtml::tag('ul',$this->htmlOptions,implode("\n",$buttons)); echo $this->footer; }
Как вы видите, CLinkPager
действительно не делает ничего, кроме вызова createPageButtons
. Таким образом, вы можете переопределить run
и динамически установить значение $this->lastPageLabel
прежде чем позволить запустить код Yii, например:
public function run() { $this->lastPageLabel = $this->getPageCount(); parent::run(); }
Ну, это хорошо. Нам удалось достичь этой цели, переопределив только один метод и написание двух строк кода. В качестве дополнительного бонуса в нашем коде нет ничего, что необходимо синхронизировать с Yii, если в будущем реализация CLinkPager
изменится.
С другой стороны, во всех этих решениях возникает проблема, которая может быть проблематичной: когда кто-то пишет представление, которое использует наш пользовательский класс пейджера, они могут не знать, что мы фактически переопределяем значение lastPageLabel
! Представьте себе: «Почему это не выводит ярлык, на который я говорю?» спутанность сознания.
К счастью, вы можете получить свой пирог и съесть его, переопределив CLinkPager::init
следующим образом:
public function init() { // "Hijack" the default values for properties that the user did not set. // This allows the user to still override this if they want to. if($this->nextPageLabel===null) $this->nextPageLabel='<'; if($this->prevPageLabel===null) $this->prevPageLabel='>'; if($this->firstPageLabel===null) $this->firstPageLabel='1'; if($this->lastPageLabel===null) $this->lastPageLabel=$this->getPageCount(); // and let Yii do the rest like it always does parent::init(); }
Затем вы можете настроить свое представление для использования этого пейджера, и все будет работать отлично, без каких-либо дополнительных аплодисментов:
'pager' => array('class' => 'CustomLinkPager'),