vnořené komponenty a práce s parametry
- vojty
- Člen | 19
Čau kluci,
chtěl bych se podělit s problémem, který u mě nastal při upgradu na Nette 2.0.10.
V presenteru vytvářim komponentu Jedna která obsahuje
komponentu Druha
Presenter
public function createComponentJedna() {
return $this->context->createJedna();
}
V komponentě Prvni mam tovarnicku na komponentu Druha
public function createComponentDruha() {
return new \MyComponents\Druha();
}
Druha.php
public function handleAdd($id) {
dump($id);
}
druha.latte
<a href="{link add! id => $sticker->id}">add</a>
vydím, že link se vytvoří správně: ?prvni-druha-id=54&do=prvni-druha-add. Handler se zavola ale proměnna $id je NULL. Ve verzi 2.0.6 mi toto všechno projde a proměnná se naplní správně. Dělám něco v zásadě špatně?
- vojty
- Člen | 19
<?php
namespace Chief\Components;
use \Nette\Utils\Html;
use \Chief\ORM\Facade;
use \Chief\Translator;
class FileBrowser extends \Nette\Application\UI\Control
{
/** @var \Nette\Application\UI\Presenter $presenter */
protected $presenter;
/** @var Translator $translator */
protected $translator;
/** @var FileBoxSet */
protected $fileBoxSet;
/** @var Object $orm */
protected $orm;
/**
* @param Translato $translator
* @param Object $orm
*/
function __construct($translator, $orm)
{
$this->translator = $translator;
$this->orm = $orm;
$this->monitor('\Nette\Application\UI\Presenter');
}
/**
* @param \Nette\Application\UI\Presenter $presenter
*/
protected function attached($presenter)
{
parent::attached($presenter);
if ($presenter instanceof Presenter) {
$this->presenter = $presenter;
if ($presenter->isAjax()) {
$this->invalidateControl();
}
}
}
/**
* Render
*/
public function render()
{
$template = $this->createTemplate();
$template->count = $this->getFiles();
$template->setTranslator($this->translator);
$template->info = $this->orm->fileFacade->loadInfo();
$template->setFile(dirname(__FILE__) . '/fileBrowser.latte');
$template->render();
}
/**
* Get files
*/
protected function getFiles()
{
$paginator = $this['paginator']->getPaginator();
$count = $this->orm->fileFacade->countByStickers($this['stickers']->getSelected());
$paginator->itemCount = $count;
$files = $this->orm->fileFacade->loadByStickers($this['stickers']->getSelected(), null, null, $paginator->itemsPerPage, $paginator->offset);
$this['fileBoxSet']->SetFiles($files);
return $count;
}
/**
* @return VisualPaginator
*/
public function createComponentPaginator() {
$pg = new \VisualPaginator();
$pg->paginator->itemsPerPage = 40;
return $pg;
}
/**
* @return FileBoxSet
*/
public function createComponentFileBoxSet() {
return $this->fileBoxSet;
}
/**
* @return Stickers
*/
public function createComponentStickers() {
$s = new \Chief\Components\Stickers($this->translator);
$s->setStickerTypes(array(1)); // set file sticker type
$s->setDataSource($this->orm->stickerFacade);
// set callback
$browser = $this;
$s->setMyCallback(function($selected) use ($browser) {
$browser['paginator']->page = $browser['paginator']->paginator->page = 1;
});
return $s;
}
/**
* @param FileBoxSet $fbs
*/
public function setFileBoxSetComponent($fbs)
{
$this->fileBoxSet = $fbs;
}
/**
* @return FileBoxSet
*/
public function getFileBoxSetComponent()
{
return $this->fileBoxSet;
}
}
namespace Chief\Components;
use \Nette\Application\UI\Presenter;
use \Nette\Utils\Html;
use \Chief\ORM\Facade;
use \Chief\Translator;
class Stickers extends \Nette\Application\UI\Control
{
/** @persistent array */
public $selected = array();
/** @var Facade\StickerFacade $stickerFacade */
protected $stickerFacade;
/** @var Translator $translator */
protected $translator;
/** @var array $stickerTypes */
protected $stickerTypes = array();
/** @var array $stickers */
protected $stickers;
/** @var string $orderBy */
protected $orderBy = null;
/** @var calback $myCallback */
protected $myCallback;
/** @var string $stickerTemplate */
protected $stickerTemplate = 'stickers.latte';
/**
* @param \VisualPaginator $paginator
*/
function __construct(Translator $translator)
{
$this->monitor('\Nette\Application\UI\Presenter');
$this->translator = $translator;
}
/**
* @param Presenter $controler
* @return type
*/
protected function attached($controler)
{
parent::attached($controler);
if(!$controler instanceof Presenter) return;
if($controler->isAjax()) {
$this->invalidateControl('stickers');
}
}
public function render()
{
$template = $this->createTemplate();
$template->setTranslator($this->translator);
$template->stickers = $this->getStickers();
$template->selected = $this->getSelected();
$template->setFile(dirname(__FILE__) . '/' . $this->getStickerTemplate());
$template->render();
}
/**
* @param Facade\StickerFacade $source
* @return Stickers
*/
public function setDataSource(Facade\StickerFacade $source)
{
$this->stickerFacade = $source;
return $this;
}
/**
* @return Facade\StickerFacade
*/
public function getDataSource()
{
return $this->stickerFacade;
}
/**
* Get stickers
* @return array
*/
public function getStickers()
{
foreach($this->stickerTypes as $type) {
$criteria['stickerType'] = $type;
}
return $this->stickerFacade->loadBy($criteria, $this->orderBy);
}
/**
* Add sticker
* @param int $id
*/
public function handleAdd($id)
{
if (!in_array($id, $this->selected)) {
$this->selected[$id] = $id;
}
if ($this->myCallback) $this->callSelectedCallback($this->selected);
}
/**
* Remove sticker
* @param int $id
*/
public function handleRemove($id)
{
if (in_array($id, $this->selected)) {
unset($this->selected[$id]);
$this->template->selected = $this->selected;
}
if ($this->myCallback) $this->callSelectedCallback($this->selected);
}
/**
* Callback
* @param array $selected
* @return callback
*/
private function callSelectedCallback($selected)
{
if(is_callable($this->myCallback)){
return call_user_func($this->myCallback, $selected);
}
return $this->myCallback;
}
/**
* Set callback
* @param type $callback
*/
public function setMyCallback($callback)
{
$this->myCallback = $callback;
}
/**
* Get sticker types
* @return array
*/
public function getStickerTypes()
{
return $this->stickerTypes;
}
/**
* @param array $types
* @return Stickers
*/
public function setStickerTypes(array $types)
{
$this->stickerTypes = $types;
return $this;
}
/**
* Get selected
* @return array
*/
public function getSelected()
{
return $this->selected;
}
/**
* @param array $selected
* @return Stickers
*/
public function setSelected(array $selected)
{
$this->selected = $selected;
return $this;
}
public function getStickerTemplate() {
return $this->stickerTemplate;
}
public function setStickerTemplate($stickerTemplate) {
$this->stickerTemplate = $stickerTemplate;
}
}
- Tomáš Brchaň
- Člen | 13
Ahoj všem, objevil jsem podobný problém, ovšem s formuláři.
Na základě https://blog.nette.org/…-and-pure-js
jsem chtěl měnit jiný select box (vše ve vnořené komponentě). Nicméně
mi to nebere hodnotu $value v handleru.
Když napíši:
<a href="{link companyChange! value => 3}">change</a>
vygeneruje se mi správně odkaz
?prvniKomponenta-druhaKomponenta-value=3&do=prvniKomponenta-druhaKomponenta-companyChange
a vše funguje, jak má.
Ale select, resp. js z návodu vytvoří
?do=prvniKomponenta-druhaKomponenta-companyChange$value=3
A v tomto případě mi handleCompanyChange($value) vrátí $value = NULL.
Kde je chyba? Je to problém js kódu, Nette nebo prostě moje, že ten parametr musím tahat jinak?
Zatím jsem to vyřešil přes js, ale má někdo lepší nápad než tento?
<script>
var link = '{link {$link}! value => "changeMe"}';
link = link.replace("&", "&");
$('#{$control["barterParticipantForm"][$input]->htmlId}').on('change', function() {
var value = $(this).val();
var url = link.replace("changeMe", value);
$.nette.ajax({
type: 'GET',
url: url
});
});
</script>
Editoval Tomáš Brchaň (31. 5. 2013 11:06)