Dynamické komponenty – problém s překreslováním
- ragulin
- Člen | 58
Ahoj,
Po určité době jsem se od dynamických snippetů ,které nejsou pro mě
ideální přesunul k cestě komponent. Snažím se zprovoznit si dynamickou
komponentu s AJAX řešením, mám to napsané nějak následovně…
Popis problému:
Pokud nyní kliknu na tlačítko „Zveřejněno na website“ , proběhne mi
v tracy:
Test:test
testControl-131-itemId = 131
do = testControl-131-test
Což je asi v pořádku, v XHR vidím, že snippet proběhl a překleslil se. Tlačítko se však nezmění. Místo toho vyskočí nad tabulku a změní se až při dalším kliknutí na něj. Zápis do DB ale probíhá dle tracy už při prvním kliknutí…
Děkuji za případnou radu, mezitím zkouším dál, co by mohlo být špatně.
O co v kodu jde:
Tahám si z DB seznam nějakých itemů, které řadím do tabulky. Ke
každému itemu chci mít tlačítko, které bude ajaxově reagovat a zapisovat
něco k danému itemu do DB zpět.
TestPresenter
protected function createComponentTestControl()
{
$allItems = $this->itemModel->getAllItems(null, null)->fetchAssoc('id');
return new Multiplier (function ($itemId) use ($allItems) {
return new TestControl($allItems[$itemId]);
});
}
public function renderTest()
{
$allItems = $this->itemModel->getAllItems(null, null)->fetchAll();
$this->template->itemsInfo = $allItems;
}
}
TestControl
public function __construct($item = null)
{
$this->item = $item;
}
public function render()
{
$this->template->itemInfo = $this->item;
$this->loggedUser = $this->presenter->user->getId();
$this->template->render(__DIR__ . '/templates/test.latte');
}
public function handleTest($itemId)
{
$data = 1;
$this->itemId = $itemId;
$this->presenter->itemModel->updateItemWebsite($data, $this->itemId, $this->loggedUser);
if ($this->presenter->isAjax()) {
$this->redrawControl();
} else {
$this->presenter->redirect('this');
}
}
}
šablona componenty
{snippet}
<tr>
<td>{$itemInfo['id']}</td>
<td> {if $itemInfo['on_website'] == null}
<a class="btn btn-primary btn-sm ajax" n:href="test!,$itemInfo['id']">Zveřejněno na website </a>
{else}
<a class="btn btn-success btn-sm disabled ajax">Ano</a>
{/if}
</td>
</tr>
{/snippet}
šablona preseter test.latte
{block content}
<table class="table">
<thead>
<tr>
<th>Test1</th>
<th>Test2</th>
</tr>
</thead>
<tbody>
<tr n:foreach="$itemsInfo as $itemInfo">
{control testControl-$itemInfo->id}
</tr>
</tbody>
</table>
{/block}
Editoval ragulin (12. 7. 2019 10:50)
- David Matějka
- Moderator | 6445
Ahoj, problem je, ze do komponenty posíláš Item ve stavu, ve kterém si ji
natáhnul z databáze. poté provedeš update, ale v this->item zůstane
původní (neaktualizovaná) hodnota. řešením je tedy poté
aktualizovat $this->item
- ragulin
- Člen | 58
David Matějka napsal(a):
Ahoj, problem je, ze do komponenty posíláš Item ve stavu, ve kterém si ji natáhnul z databáze. poté provedeš update, ale v this->item zůstane původní (neaktualizovaná) hodnota. řešením je tedy poté aktualizovat
$this->item
Děkuji za radu! Upravil jsem tedy handleTest v test Control následovně:
public function handleTest($itemId)
{
$data = 1;
$this->itemId = $itemId;
$this->presenter->itemModel->updateItemWebsite($data, $this->itemId, $this->loggedUser);
$this->item = $this->presenter->itemModel->getItemInfo($this->itemId)->fetch(); /*added*/
if ($this->presenter->isAjax()) {
$this->redrawControl();
} else {
$this->presenter->redirect('this');
}
}
Nyní se již AJAX provede správně, nicméně tlačítko vyskočí zase nad tabulku (již má správně status „Ano“), ale v tabulce zůstane pořád to staré a změní se až po refresh. To bude ale asi problém někde v tom latte, takže pokud by někdo řešil stjený problém, výše zmíněné je správné řešení