vnořené snippety – špatná invalidace snippetů
- tttpapi
- Člen | 100
Ahoj,
mám nette verze 2.0.3.
Potřebuji použít vnořené snippety.
Pokud používám samotné snippety bez vnořených, tak všechno funguje
správně.
Pokud však vnořím snippety, tak mi to začne invalidovat úplně jiné věci,
než které invaliduji přes invalidate control.
Kód
{snippet discussionSnippet}
{form discussionForm class => ajax}
<div>{input text}</div>
<div>{input publish}{label publish /}{input submit}</div>
{/form}
{if $myDiscussionPosts != FALSE}
{? $i = 0}
{foreach $myDiscussionPosts as $post}
<div>
<p>{$post['text']}</p>
<span>
<a n:href="commentPost! $post['id']" class="ajax">
{_"DISCUSSION_ADD_YOUR_COMMENT"}
</a>
</span>
<span>
<a n:href="ratePost! $post['id'], -1" class="ajax">-1</a>
{$post['rating']}
<a n:href="ratePost! $post['id'], 1" class="ajax">+1</a>
</span>
<span>{$post['created_on']}</span>
{snippet postComment$i}
{ifset $showComment[$i]}
<div>
{form commentForm class => ajax}
{input postId}
<div>{input comment}</div>
<div>{input submit}</div>
{/form}
</div>
{/ifset}
{/snippet}
</div>
{? $i++}
{/foreach}
{/if}
{/snippet}
$this->template->showComment = array();
$this->template->showComment[$i] = TRUE;
$this->invalidateControl('discussionSnippet'.$i);
}
public function handleRatePost($postId, $value) {
...
$this->invalidateControl('discussionSnippet');
}
Pokud odstraním vložený snippet, tak se správně volá snippet discussionSnippet. Jakmile se vloží vnořené snippety, začne to místo hlavního snippetu invalidovat jen vnořené. A pokud chci invalidovat vložený, tak se neinvaliduje vůbec nic. Konzele hlásí jen {„state“:[]}.
Editoval tttpapi (22. 8. 2012 10:28)
- Vojtěch Dobeš
- Gold Partner | 1316
To je korektní chování (myslím) dynamických snippetů. Je třeba invalidovat jak konkrétní, tak ten obalující. Podrobnější čtení např.: https://doc.nette.org/…mic-snippets
- tttpapi
- Člen | 100
Tak jsem to předělal na komponenty.
A stále se mi hodnocení příspěvku neinvaliduje. Změna se provede, vše
v databázi je. Když stránku refreshnu, tak se změny objeví.
Konzole však vrací stále prázný {„state“:[]}.
protected function createComponentShowPosts() {
$translator = $this->translator;
$uniModel = $this->uniModel;
return new Nette\Application\UI\Multiplier(function ($id) use ($translator, $uniModel) {
return new DiscussionPost($translator, $id, $uniModel);
});
}
A komponenta pro hodnocení
latte
<div>{$post['text']}</div>
<div>
{snippet}
<a n:href="ratePost! $post['id'], -1" class="ajax">-1</a>
{$post['rating']}
<a n:href="ratePost! $post['id'], 1" class="ajax">+1</a>
{/snippet}
<span>{$post['created_on']}</span>
</div>
php
public function handleRatePost($postId, $value) {
$this->ratePost($postId, $value);
$this->invalidateControl();
}
- Vojtěch Dobeš
- Gold Partner | 1316
Hm, this is weird. Nechceš někam nahrát nebo poslat celé soubory? Tohle by to dělat nemělo.
Voláš v konstruktoru parent?
Editoval vojtech.dobes (17. 8. 2012 0:15)
- tttpapi
- Člen | 100
Tady je kód.
vytvoření diskuze
use Nette\Application\UI;
class Discussion extends UI\Control {
private $translator;
private $uniModel;
private $presenter;
private $profileId;
private $commentedPostId;
private $posts;
public function __construct($translator, UniversalModel $universalModel,
$presenter, $profileId) {
parent::__construct();
$this->translator = $translator;
$this->presenter = $presenter;
$this->uniModel = $universalModel;
$this->profileId = $profileId;
$this->posts = $this->getMyDiscussionPosts();
}
public function render() {
$this->template->setFile(__DIR__ . '/Discussion.latte');
$this->template->setTranslator($this->translator);
$this->template->discussionPosts = $this->getMyDiscussionPosts();
$this->template->commentedPostId = $this->commentedPostId;
$this->template->render();
}
private function discussionForm() {
...
}
public function discissionFormSubmitted($form) {
...
$form->setValues(array(), TRUE);
$this->invalidateControl('discussionSnippet');
}
public function createComponentDiscussionForm() {
return $this->discussionForm();
}
public function getMyDiscussionPosts() {
...
return $discusionPosts; // vrací pole s příspevkama
}
protected function createComponentShowPosts() {
$translator = $this->translator;
$uniModel = $this->uniModel;
return new Nette\Application\UI\Multiplier(function ($id) use ($translator, $uniModel) {
return new DiscussionPost($translator, $id, $uniModel);
});
}
}
latte diskuze
{block content}
<h1>Diskuze</h1>
{snippet discussionSnippet}
{form discussionForm class => ajax}
<div>{input text}</div>
<div>{input publish}{label publish /}{input submit}</div>
{/form}
{foreach $discussionPosts as $post}
{control "showPosts-".$post['id']}
{/foreach}
{/snippet}
{/block}
Hodnocení příspěvku
use Nette\Application\UI;
class DiscussionPost extends UI\Control {
private $translator;
private $postId;
private $uniModel;
private $post;
public function __construct($translator, $postId, UniversalModel $universalModel) {
parent::__construct();
$this->translator = $translator;
$this->postId = $postId;
$this->uniModel = $universalModel;
$this->post = $this->getPost($postId);
}
public function render() {
$this->template->setFile(__DIR__ . '/DiscussionPost.latte');
$this->template->setTranslator($this->translator);
$this->template->post = $this->post;
$this->template->render();
}
public function handleRatePost($postId, $value) {
$this->ratePost($postId, $value);
$this->invalidateControl();
}
private function ratePost($postId, $value) {
... uložení do db
}
public function getPost($id) {
... načtení příspěvku z db se změněným hodnocením
}
}
latte
{snippet}
<div>{$post['text']}</div>
<div>
<a n:href="ratePost! $post['id'], -1" class="ajax">-1</a>
{$post['rating']}
<a n:href="ratePost! $post['id'], 1" class="ajax">+1</a>
<span>{$post['created_on']}</span>
</div>
{/snippet}
- Vojtěch Dobeš
- Gold Partner | 1316
Zatím odpověď neznám, pokusím se to vyzkoušet, jen dotaz: proč si tam
předáváš presenter v konstruktoru? Každý UI\Control
má
presenter vždy dostupn.