Stránkování – Cannot read an undeclared property…

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Proton
Člen | 12
+
0
-

Zdravím, snažím se udělat stránkování, formou jsem se nechal inspirovat u známého tutoriálu – https://pla.nette.org/…ivajici-ajax

Bohužel jsem se zasekl při tom, že mi laděnka píše „Cannot read an undeclared property HomepagePresenter::$posts.“ a označila mi řádek:

$dataSource = $this->posts->getDataSource();

Přikládám ještě celej kód co mám v presenteru:

public function renderDefault(){

$dataSource = $this->posts->getDataSource();
$dataSource->orderBy('date_added', dibi::DESC);

$paginator = $this['paginator']->getPaginator();
$paginator->itemCount = $dataSource->getTotalCount();
$dataSource->applyLimit($paginator->itemsPerPage, $paginator->offset);

$this->template->posts = $dataSource;
}

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

Díky za případný tip :)

Editoval Proton (14. 2. 2012 20:21)

Elijen
Člen | 171
+
0
-

Jak rika hlaska: $this->posts neni definovano. Kde tu property nastavujes?

Editoval Elijen (14. 2. 2012 20:27)

Proton
Člen | 12
+
0
-

Ajo, dík, už mě to trklo :) Samozřejmě, místo $this->posts jsem tam měl mít $this->model :)

Teď už jen musím vyřešit jak napsat dotaz do databáze.

Tohe:

$this->database->select('*')->where(array('status' => 'ok'))->order('date_added DESC')->fetchAll($offset, $limit);

mi vyhazuje chybu – Call to undefined method Nette\Database\Connection::select().

Předpokládám že je to problém s verzí Nette – používám aktuální 2.0., bohužel nemůžu najít jak by to aktuálně mělo vypadat.

Etch
Člen | 403
+
0
-

S \Nette\Database by tam mělo myslím být něco jako:

$this->database->table('tabulka')
		->where(array('status' => 'ok'))
		->order('date_added DESC')
		->fetchAll($offset, $limit);

ale možná se pletu, protože \Nette\Database nepoužívám a používám Dibi.

Proton
Člen | 12
+
0
-

Tohle prozměnu píše Call to undefined method Nette\Database\Table\Selection::fetchAll().

Já v té dokumentaci, ani API správnej způsob prostě nemůžu najít

Editoval Proton (14. 2. 2012 21:32)

Etch
Člen | 403
+
0
-

Nějak cca takhle by to mělo být:

$data = $this->database->table('tabulka')
                ->where(array('status' => 'ok'))
                ->order('date_added DESC');

$paginator = $this['paginator']->getPaginator();

$paginator->itemCount = count($data);

$this->template->posts = $data->limit($limit, $offset);;

nebo aspoň tak jsem to pochopil z API

Jan Endel
Člen | 1016
+
0
-

to fetchAll vyhod, a pak nad tím budeš moci iterovat způsobem popsaným v dokumentaci. (Přes foreach)

Elijen
Člen | 171
+
0
-

Metoda table vraci objekt Selection a ten nema metodu fetchAll. Misto fetchAll bych pouzil fetchPairs a limit.

$articles = $this->database->table('article')
	->select('*')
	->where(array('status' => 'ok'))
	->order('date_added DESC')
	->limit($limit, $offset)
	->fetchPairs('id');

Jinak to fetchPairs na konci volat nemusis. S objektem Selection muzes pracovat jako by to byl uz rovnou vysledek (pole/objekt) a query + fetch se provede „magicky“ na pozadi az kdyz je treba. Takze kdyz si odmyslis posledni radek z kodu vyse, tak muzes pokracovat:

foreach($articles as $article) {
	echo $article->text;
}
Proton
Člen | 12
+
0
-

Omlouvám se za vetší odmlku :)
Udělal jsem to tedy tak jak bylo řečeno, ale nyní mi laděnka píše „Component with name ‚vp‘ does not exist.“ Nějak se mi nechce načíst komponenta a já nevím proč.

V šabloně mám toto:

{block content}
          {foreach $posts as $post}
          <div class="item">
              <h2><a n:href="Posts:View id => $post->id">{$post->title}</a></h2>
              <p>{$post->description}</p>
              <p><strong>Vloženo:</strong> {$post->date_added|date:'d.m.Y'}</p>
           </div>
           {/foreach}
           {control vp}
{/block}

Jak je to tedy správně?

Presenter aktuálně vypadá takto:

public function renderDefault(){
$vp = new VisualPaginator($this, 'paginator');
$paginator = $vp->getPaginator();
$paginator->itemsPerPage = 5;
$paginator->itemCount = $this->model->countPosts();
$rows = $this->model->getAll($paginator->offset, $paginator->itemsPerPage);
$this->template->rows = $rows;
}

a jak model:

public function getAll($offset, $limit) {
return $this->database->table('posts')
->select('*')
->where(array('status' => 'ok'))
->order('date_added DESC')
->limit($limit, $offset)
;}


public function countPosts() {
return $this->database->fetchAll("SELECT COUNT(*) FROM posts");
}

Editoval Proton (19. 2. 2012 14:09)

Proton
Člen | 12
+
0
-

Jaj, tak už vím kde byla chyba – {control paginator} jsem měl mít místo {control vp} :)

Teď se mi akorát nezobrazuje samotné stránkování. Ale to už je zas jiná chybka :)

Editoval Proton (19. 2. 2012 14:20)

Jan Endel
Člen | 1016
+
0
-

VisualPaginator je chytrák, ukazuje se jen když je potřeba, máš dostatečný počet položek?

Proton
Člen | 12
+
0
-

Ano, položek mám asi 15. Problém je v tom, že mi to ten počet položek nepočítá správně. A já zatím nepřišel na to proč. Takže se stránkování skutečně nezobrazuje proto, že si myslí že se rozbrazit nemá :)

Když počet položek do stránkování nastavím ručně, tak se zobrazí a funguje perfektně.

Editoval Proton (19. 2. 2012 14:56)

Proton
Člen | 12
+
0
-

Tak už to mám, přepsal jsem dotaz na počet položek v databázi takto a už to funguje. Ještě ten dotaz musím trochu upravit aby to počítalo jen schválen položky, ale to hlavní je hotové :) Díky všem za pomoc.

return $this->database->table('posts')->count('*');
Jan Endel
Člen | 1016
+
0
-

Máš chybu v modelu:

public function countPosts() {
	return $this->database->fetchColumn("SELECT COUNT(*) as cnt FROM posts WHERE status = 'ok'");
}

Editoval pilec (19. 2. 2012 15:12)

Proton
Člen | 12
+
0
-

Ano, to je přesně to co jsem hledal. Díky