Komponenta pro vkládání a zobrazení komentářů
- konva
- Člen | 88
Ahoj,
chtěl bych vytvořit komponentu, která mi zobrazí jednoduchou diskusi (resp.
komentáře) pod každým článkem. Chci ji ale používat i jinde než jen
u článků, např. u fotky v galerii.
Potřeboval bych aby zobrazila výpis komentářů a jednoduchý formulář pro
vložení komentáře pokud je uživatel přihlášen.
Momentálně mám tento presenter pro zobrazení detailu článku
<?php
class ArticlePresenter extends BasePresenter
{
/** @var \Components\Comments @inject */
public $commentsFactory;
private $article;
function __construct(Model\ArticleModel $article){
$this->article = $article;
}
public function renderDetail($key = ''){
$article = $this->article->getByKlic($key);
if (!$article) {
$this->error();
}
$this->template->article = $article;
}
function createComponentComments(){
$comments = $this->commentsFactory;
return $comments;
}
}
?>
Toto mám v šabloně pro detail článku
<?php
{control comments $article->id, TRUE}
?>
A takhle mám nadefinovánu komponentu
<?php
namespace Components;
class Comments extends Control
{
private $db;
public function __construct(\Nette\Database\Context $db){
parent::__construct();
$this->db = $db;
}
function createForm(){
$form = new UI\Form;
$form->addTextArea('content', 'Text:')
->setRequired();
$form->onSuccess[] = $this->addFormSucceeded;
$form->addSubmit('send', 'Odeslat');
return $form;
}
function addFormSucceeded($form){
$vals = $form->getValues();
//.....................
}
function getItems($id){
return $this->db->table('diskusePolozka')->where('mainId', $idRodic);
}
public function render($id, $showForm){
$this->template->polozky = $this->getItems($id);
$this->template->form = $this->createForm();
$this->template->setFile(__DIR__ . '/comments.latte');
$this->template->render();
}
}
?>
Nevím ale jak zpracovat odeslaný formulář v komponentě. V šabloně
článku, kam komponentu vkládám chci jen odkázat na komponentu a předat Id
článku, ke kterému komentáře náleží a chtěl bych v komponentě data
z formuláře uložit do DB. Nejlépe ajaxově, ale může být
i normálně.
Používám nette 2.2-dev.
Za každou radu díky. Jsem Nettista začátečník, tak prosím
o schovívavost :)
Lukáš
Editoval konva (22. 1. 2014 19:14)
- David Matějka
- Moderator | 6445
nejdriv par poznamek:
- vyhni se posilani parametru do komponenty v sablone (to
{control comments $article->id, true}
), to true pro (ne)zobrazeni formu je jeste ok, ale posilat id timhle zpusobem muze byt pozde - komponentu si (nikdy) neregistruj jako sluzbu, jen si na ni vytvor tovarnicku
- pro form si vytvor sub komponentu v te komponente s komentarema
a kod:
namespace Components;
class Comments extends Control
{
private $db;
private $id;
public function __construct($id, \Nette\Database\Context $db){
// parent::__construct(); v komponentach neni nutno volat rodice
$this->db = $db;
$this->id = $id;
}
function createComponentForm(){ //createComponent, aby to byla klasicka komponenta
$form = new UI\Form;
$form->addTextArea('content', 'Text:')
->setRequired();
$form->onSuccess[] = $this->addFormSucceeded;
$form->addSubmit('send', 'Odeslat');
return $form;
}
function addFormSucceeded($form){
$vals = $form->getValues();
//.....................
}
protected function getItems($id){
return $this->db->table('diskusePolozka')->where('mainId', $idRodic);
}
public function render($showForm = TRUE){
$this->template->showForm = $showForm;
$this->template->polozky = $this->getItems($this->id);
$this->template->setFile(__DIR__ . '/comments.latte');
$this->template->render();
}
}
smazal jsem to posilani formu do sablony, tam pouzij jen
{control form}
pripadne makro {form}
pak si vytvor tovarnicku
namespace Components;
interface CommentsFactory
{
/**
* @return Comments
*/
public function create($id);
}
tu registrujes v neonu (do sekce services)
services:
-
implement: Components\CommentsFactory
class: Components\Comments
arguments: [%id%]
parameters: [id]
a v presenteru
class ArticlePresenter extends BasePresenter
{
/** @var \Components\CommentsFactory @inject */
public $commentsFactory;
private $article;
function __construct(Model\ArticleModel $article){
$this->article = $article;
}
public function renderDetail($key = ''){
$article = $this->article->getByKlic($key);
if (!$article) {
$this->error();
}
$this->template->article = $article;
}
function createComponentComments(){
$comments = $this->commentsFactory->create($this->getParameter('key');
return $comments;
}
}
a v sablone uz bez id
{control comments}
Editoval matej21 (22. 1. 2014 19:23)
- konva
- Člen | 88
Díky za supr rychlou odpověď. Ještě mám dvě otázečky.
V tom
<?php
$this->getParameter('key');
?>
si predavam „slug“ (textovy klic ke clanku)
Pro zobrazeni komentaru ale potrebuji ID clanku. Rikal jsem si, ze si teda v prezenteru vytvorim lokalni promenou a v metode renderDetail ji naplnim (viz. nize), ale pri odeslani formulare se asi renderDetail nezpousti protoze mi to vrati komentare ke vsem clankum … Jak to nejlepe vyresit?
<?php
public function renderDetail($klic = ''){
$clanek = $this->clanek->getByKlic($klic);
......
$this->idClanek = $clanek->ckId;
}
function createComponentComments(){
$comments = $this->commentsFactory->create($this->idClanek);
return $comments;
}
?>
Mohl bych si to ID zjistit z toho klice pri dotazu do databaze na ty prispevky, ale prijde mi to zbytecne kdyz to ID muzu ziskat z detailu clanku.
A ještě jedna asi blbá otázka …
Jaký je rozdíl v neonu mezi „arguments“ a „parameters“?
Díky za odpověď
Lukáš
- David Matějka
- Moderator | 6445
aha, ze je tam slug jsem si nevsiml.. ve startupu ne, startup je spolecny pro vsechny akce, pokud by jich bylo vice. spravne bys to mel nacitat v actionDetail metode, cely kod muze pak vypadat treba takhle:
class ArticlePresenter extends BasePresenter
{
/** @var \Components\CommentsFactory @inject */
public $commentsFactory;
private $articleModel; //prejmenoval jsem to, at se to rozpozna od article samotneho
private $article;
function __construct(Model\ArticleModel $article){
$this->articleModel = $article;
}
public function actionDetail($key = '')
{
$this->article = $this->articleModel->getByKlic($key);
if (!$this->article) {
$this->error();
}
}
public function renderDetail(){
$this->template->article = $this->article;
}
function createComponentComments(){
$comments = $this->commentsFactory->create($this->article->id);
return $comments;
}
}
nebo vlatne nemusis do create metody posilat jen id, ale klidne cely article, to uz je na tobe :)
Jaký je rozdíl v neonu mezi „arguments“ a „parameters“?
parametry jsou to, co posilas do create metody v presenteru, argumenty jsou to, co se potom posle do konstruktoru komponenty. v pripade tehle tovarnicek to vetsinou mapujes 1:1, v argumentech ale muze treba navic byt i nejaka zavislost (ktera neni autowired) apod.
Editoval matej21 (23. 1. 2014 13:22)
- Pavel Macháň
- Člen | 282
konva napsal(a):
diky za odpověď. Stále si pročítám i dokumentaci a použít „action“ by mě nenapadlo i když to tam teď vidím. Tohle řešení je supr.
Díky
Lukáš
Tedle schémátko životního cyklu presenteru si doporučuju někde vystavit :)

Editoval EIFEL (23. 1. 2014 14:25)