@persistent vars troubles ?!

7 years ago

bestxp
Member | 6
+
0
-

Hello, a have one trouble with VisualPaginator

Some code
Component RecentNews

<?php
/**
 * Created by JetBrains PhpStorm.
 * User: bestxp
 * Date: 21.06.12
 * Time: 23:37
 * To change this template use File | Settings | File Templates.
 */

use Nette\Application\UI,
Nette\Database\Table\Selection;

Class RecentNews extends UI\Control {

    /** @var \Nette\Database\Table\Selection */
    protected $_news;

    public function __construct(Selection $news) {
        parent::__construct();
        $this->_news = $news;
    }

    protected function _createNews() {

                $this->_news->order('date_create DESC')->where('active = 1');
                $vp = new VisualPaginator($this, 'vp');
                $pagination = $vp->getPaginator();
                $pagination->setItemCount($this->_news->count('id'));
                $pagination->setItemsPerPage(2);
                $this->_news->limit($pagination->itemsPerPage, $pagination->offset);
                break;

        return $this->_news;
    }

    public function render() {
        $this->template->setFile(__DIR__ . "/RecentNews.latte");
        $this->template->news = $this->_createNews();
        $this->template->render();
    }
}
?>
//and visual paginator with fix namespace
use Nette\Application\UI\Control;
use Nette\Utils\Paginator;


/**
 * Visual paginator control.
 *
 * @author     David Grudl
 * @copyright  Copyright (c) 2009 David Grudl
 * @package    Nette Extras
 */
class VisualPaginator extends Control {
    /** @var Paginator */
    private $paginator;

    /** @persistent */
    public $page = 1;


    /**
     * @return Nette\Utils\Paginator
     */
    public function getPaginator() {
        if (!$this->paginator) {
            $this->paginator = new Paginator;
        }
        return $this->paginator;
    }


    public function render() {
        $paginator = $this->getPaginator();
        $page      = $paginator->page;
        if ($paginator->pageCount < 2) {
            $steps = array($page);

        } else {
            $arr      = range(max($paginator->firstPage, $page - 3), min($paginator->lastPage, $page + 3));
            $count    = 4;
            $quotient = ($paginator->pageCount - 1) / $count;
            for ($i = 0; $i <= $count; $i++) {
                $arr[] = round($quotient * $i) + $paginator->firstPage;
            }
            sort($arr);
            $steps = array_values(array_unique($arr));
        }

        $this->template->steps     = $steps;
        $this->template->paginator = $paginator;
        $this->template->setFile(dirname(__FILE__) . '/template.phtml');
        $this->template->render();
    }


    /**
     * Loads state informations.
     *
     * @param  array
     *
     * @return void
     */
    public function loadState(array $params) {
        parent::loadState($params);
        $this->getPaginator()->page = $this->page;
    }

}

The components are created, pagination appears everything is fine.
But go to the link … does not give any result, that is, / ** @ persistent * / does not work, or I miss something somewhere.

I would like to hear a clue where to look, as a matter of fact one of the examples

Maybe not good, but there is a need to use the pagination of this component is not tied to the current page, it is possible to change the data in any location.

Or it seems to me that there is a bug crept

7 years ago

duke
Member | 646
+
0
-

You should create the paginator as a component using factory method like this:

protected function createComponentPaginator()
{
    $visualPaginator = new VisualPaginator();
    // $visualPaginator->paginator->itemsPerPage = $this->getItemsPerPage();
    return $visualPaginator;
}

Then replace the line in your code:

$vp = new VisualPaginator($this, 'vp');

with:

$vp = $this['paginator'];

And to make the paginator component persistent, add this method to your presenter:

public static function getPersistentComponents()
{
    $components = parent::getPersistentComponents();
    $components[] = 'paginator';
    return $components;
}

It is also possible to achieve the same using an annotiation rather than override of this static method, but such annotation is not automatically derived when using class inheritance (base presenters, etc.), so you would have to repeat it in all derived presenters. I therefore prefer to use this method.

7 years ago

bestxp
Member | 6
+
0
-

Thank you, interesting trick

So if I want to create components using persistent variables

  1. they need to create a Factory createComponent
  2. Specify the controller into getPersistentComponents

7 years ago

HosipLan
Moderator | 4693
+
0
-

No, if you wanna use components, you “have to” connect them within each other. So always use component factories. Even presenter itself is a (bigger) component.

Overwritting getPersistentComponents is a not the cool way. You can use annotation