Řazení s persistentním parametrem
- na1k
- Člen | 288
Ahoj, mám problém s rozchozením řazení tak, jak je popsáno v quick-startu
Možná to není tak docela problém, ale jednoduše nechápu, jak to má
fungovat. Pro úplnost přidávám kód, který by ale měl být totožný
s quick-startem (je tam nějaká omáčka okolo).
<?php
class Front_GoodsCategoriesPresenter extends Front_DefaultPresenter
{
/** @persistent */
public $order = '';
/**
* Vypsani kategorie
* @param string $id link kategorie
* @param string $orderBy
* @return void
* TODO: Tahat data z modelu
*/
public function renderDefault($id, $orderBy) {
// pripojit model
$this->model = new Goods();
$table = Goods::TABLE;
// zkusit najit podkategorie, pokud neni zadna, dostali sme se na neexistujici kategorii
$categories = $this->model->getSubCategories($id);
if ($categories === false)
$this->redirect("Front:Special:404");
parse_str($orderBy, $list);
if ($orderBy) {
if (!isset($list[$orderBy])) {
$list[$orderBy] = 'a';
} elseif ($list[$orderBy] === 'd') {
unset($list[$orderBy]);
} else {
$list[$orderBy] = 'd';
}
}
$this->order = http_build_query($list, '', '&');
// strankovani
$vp = new VisualPaginator($this, 'paginator');
$paginator = $vp->getPaginator();
$paginator->itemsPerPage = 5;
$paginator->itemCount = dibi::fetchSingle("
SELECT COUNT(*)
FROM [".$table."]
WHERE [status]=%s", 'publish', "AND ([category]=".implode(' OR [category]=', $categories), ")");
// nacteni polozek - fluent
$query = dibi::select('*')
->from($table)
->where("[category]=".implode(" OR [category]=", $categories))
->offset($paginator->getOffset())
->limit($paginator->getLength());
// nastavit razeni
$i = 1;
foreach ($list as $field => $dir) {
$query->orderBy($field, $dir === 'a' ? 'ASC' : 'DESC');
$list[$field] = array($dir, $i++);
}
// nacist
$rowset = $query->execute();
$rows = $rowset->fetchAll();
// nahradit fnodes obrazku za cesty (nechat pouze jeden obrazek)
$this->model->imageNodesToPaths(&$rows, $single=true);
$this->template->id = $id;
$this->template->order = $list;
$this->template->paginator = $vp;
$this->template->rows = $rows;
$this->template->columns = $rowset->getColumnNames();
$this->template->currentOrder = $this->order;
}
}
?>
<?php
<table class="grid" border="1">
<tr>
{foreach $columns as $column}
<th><a href="{link this, $id, $column}"
{if isset($order[$column])} class="{$order[$column][0] === 'a' ? 'asc' : 'desc'}"{/if}
>{$column}{if count($order) > 1 && isset($order[$column])} <span>{$order[$column][1]}</span>{/if}</a></th>
{/foreach}
</tr>
{foreach $rows as $num => $row}
<tr{if $iterator->isOdd()} class="alt"{/if}>
{foreach $row as $value}
<td>{=substr($value, 0, 100)}</td>
{/foreach}
</tr>
{/foreach}
</table>
{$paginator->render()}
?>
Řazení se ale chová tak, že řadí pouze podle jednoho sloupce (QS tvrdí něco jiného), a navíc se v adrese (dle mého zbytečně) předávají dva parametry (order a orderBy), které jsou ve výsledku shodné. (Myšleno tak, že link sice odkazuje na adresu s různými parametry, ale pak se to nějak přesměruje a jsou shodné.)
Proč dva parametry? A k čemu má $order
a
$orderBy
sloužit? Když jsem řešil řazení dříve (bez Nette),
stačil mi jeden parametr v odkazu, což by tady mohlo být ono
$orderBy
, které se z linku předá presenteru. K čemu je potom
druhý, persistentní parametr?
Opravdu bych ocenil, kdyby mi někdo alespoň zjednodušeně popsal tok dat. Sedím nad tím už pár hodin, nic kloudného jsem nevymyslel, a přijde mi, že čím déle to řeším, tím méně tomu kódu rozumím :( (A to QS ještě tvrdí K pochopení tohoto mechanismu opět napomůže nahlédnout do zdrojového kódu.)
- jasir
- Člen | 746
na1k napsal(a):
V rychlosti:
$order
je persistentní proměnná presenteru, která si udržuje pole (ve tvaru query stringu) sloupců podle kterých se sortuje$orderBy
je parametr metodyrenderDefault()
a potažmo linku z hlavičky tabulky, takže když uživatel klikne na jméno sloupce, jméno tohoto sloupce přijde dorenderDefault()
jako parametr
Zde máš chybu (plynoucí zřejmě z výše uvedeného nepochopení):
<?php
parse_str($orderBy, $list);
if ($orderBy) {
if (!isset($list[$orderBy])) {
$list[$orderBy] = 'a';
} elseif ($list[$orderBy] === 'd') {
unset($list[$orderBy]);
} else {
$list[$orderBy] = 'd';
}
}
?>
protože by to mělo být nějak jako:
<?php
parse_str($this->order, $list); //vyrob z persistentní proměnné order array
if ($orderBy) {
if (!isset($list[$orderBy])) {
$list[$orderBy] = 'a';
} elseif ($list[$orderBy] === 'd') {
unset($list[$orderBy]);
} else {
$list[$orderBy] = 'd';
}
}
$this->order = http_build_query($list, '', '&');
?>
Editoval jasir (17. 7. 2009 17:12)