Dynamické komponenty – problém s překreslováním

ragulin
Člen | 58
+
0
-

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
+
+1
-

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
+
0
-

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í

norbe
Backer | 405
+
0
-
  1. V latte šablonách máš 2× tag <tr> (jednou v hlavní šabloně, podruhé v komponentě)
  2. Snippet bych přesunul přímo na tag <tr>

Tzn. místo:

{snippet}
        <tr>

Bych zkusil

<tr n:snippet>
CZechBoY
Člen | 3608
+
0
-

taky ti makro snippet udělá div když nepoužíváš n:snippet