Replicator – Using $this when not in object context

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Oli
Člen | 1215
+
0
-

Ahoj,
vyskytla se mě taková chyba. používám replicator, ale potřeboval bych „replikovat“ select a radio. To mě funguje, ale jen v Apache: 2.4.2, PHP: 5.4.3 a Nette: 2.0.6.
Když to ale nahraju na server, kde je Apache: 1.3.4 (asi), PHP: 5.3 a Nette 2.0.6, tak to nefunguje a píše to chybu Using $this when not in object context na řádku

$container->addSelect("attribute", "Přívlastek", $this->dynamic->getDynamic()->fetchPairs('id', 'dynamic_name'))

Když odstraním všechny selecty a radio buttony, tak to funguje, ale s něma mě to hází tuhle chybu. Dělal jsem to v podstatě podle sandboxu replicatoru, kod mám následující:

protected function createComponentEditTrip($name)
{
    $form = new Form;

    $presenter = $this;
    $invalidateCallback = function () use ($presenter) {
        /** @var \Nette\Application\UI\Presenter $presenter */
        $presenter->invalidateControl('EditTrip');
    };
    $replicator = $form->addDynamic('trips', function (Container $container) use ($invalidateCallback)
    {

        $container->addSelect("attribute", "Přívlastek", $this->dynamic->getDynamic()->fetchPairs('id', 'dynamic_name'))
            ->setPrompt('--Vyberte--');
        $container->addSelect("specific_gallery", "Konkrétní galerie", $this->gallery->getGallery()->fetchPairs('id', 'type'));
        $container->addRadioList('with_gallery', 'Galerie:', $this->gallery->getGallery()->fetchPairs('id', 'type'))
            ->getSeparatorPrototype()->setName(NULL);

        $container->addSubmit('remove', 'Smazat')
                ->addRemoveOnClick($invalidateCallback);

        $container->addSubmit('removeAjax', 'Smazat Ajaxem')
                ->setAttribute('class', 'ajax')
                ->addRemoveOnClick($invalidateCallback);
    }, 1);

    /** @var \Kdyby\Extension\Forms\Replicator\Replicator $replicator */
    $replicator->addSubmit('add', 'Přidat dalšího')
            ->addCreateOnClick($invalidateCallback);

    $replicator->addSubmit('addAjax', 'Přidat dalšího Ajaxem')
            ->setAttribute('class', 'ajax')
            ->addCreateOnClick($invalidateCallback);

    $form->addSubmit('send', 'Zpracovat')
            ->onClick[] = callback($this, 'editTripSubmitted');

    $form->addSubmit('sendAjax', 'Zpracovat Ajaxem')
            ->setAttribute('class', 'ajax')
            ->onClick[] = callback($this, 'editTripSubmitted');

    $this[$name] = $form;
    //$form->action .= '#snippet--usersForm';
    return $form;
}

A pak to vykresluju:

{snippet editTrip}
        {form editTrip class =>"well form-vertical"}
            {control $form errors}
            {foreach $form['trips']->containers as $id => $trip}
            <div class="pair" id="attribute">
                {label trips-$id-attribute /}{input trips-$id-attribute}
            </div>
            <div class="pair with_gallery">
                {label trips-$id-with_gallery /}{input trips-$id-with_gallery}
            </div>
            <div class="pair">
                {input trips-$id-remove class=>"btn btn-primary"}
            </div>
            {/foreach}
            <div class="pair">
                {input trips-add class=>"btn btn-primary"}
            </div>

            <div class="pair">
                {input send class=>"btn btn-primary", id=>"confirm"}
            </div>
        {/form}
{/snippet}

Budu moc rád za jakoukoli radu, jak to rozchodit, i na PHP 5.3.x
Díky

stefi023
Člen | 71
+
0
-

PHP 5.3 vs 5.4 proslo zmenou, kde je mozne pouzivat $this v ramci anonymnich funkci… to co mas napsane ti v 5.4 fungovat bude.

Aby ti to fungovalo i v 5.3 musis si $this predat do anonymni funkce pomoci use (stejne jako $invalidateCallback) nejak takto:

$_this = $this;
$replicator = $form->addDynamic('trips', function (Container $container) use ($invalidateCallback,$_this)
    {

        $container->addSelect("attribute", "Přívlastek", $_this->dynamic->getDynamic()->fetchPairs('id', 'dynamic_name'))
            ->setPrompt('--Vyberte--');
	///......
}

//edit: koukam ze dost podobne to mas nahore v te definici callbacku, akorat tomu rikas presenter :)

Editoval stefi023 (1. 11. 2012 12:00)

Oli
Člen | 1215
+
0
-

Díky moc za radu! S anonymníma funkcema jsem zatím nikdy moc nedělal. Udělal jsem to jak říkáš a funguje to. Máto sice přístup jen k public proměnným, ale funguje to :-)

Filip Procházka
Moderator | 4668
+
0
-

Mimochodem, máš tam zbytečně moc tlačítek. Tohle

$container->addSubmit('remove', 'Smazat')
	->addRemoveOnClick($invalidateCallback);

$container->addSubmit('removeAjax', 'Smazat Ajaxem')
	->setAttribute('class', 'ajax')
	->addRemoveOnClick($invalidateCallback);

Jsou duplikovaná tlačítka čistě za účelem demonstrace, aby to šlo odeslat dvěma způsoby. V tvé aplikaci je takové chování absolutně zbytečné.

Oli
Člen | 1215
+
0
-

Já vím, zatím to ladím, pak to odstraním až to bude finální. ale díky ;-)