Největší záseky v Nette – drobnosti, na kterých se dá viset i několik hodin

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8228
+
+3
-

fizzy napsal(a):

Dost casto sa mi stava, ze premena z cyklu foreach mi prepise nejaku hodnotu z presenteru.

Taky se mi to párkrát stalo, zkusil jsem přidat varování a uvidíme, jak se to osvědčí.

(tyjo… už jsem tím našel chybu v jednom projektu :-) )

Šaman napsal(a):

Že si framefork zabere takhle běžné slovo proměnnou, to si myslím, že není slušné. Takže:

Framework ji nepoužívá a tedy ani nezabírá.

Šaman
Člen | 2665
+
+1
-

David Grudl napsal(a):

Šaman napsal(a):

Že si framefork zabere takhle běžné slovo proměnnou, to si myslím, že není slušné. Takže:

Framework ji nepoužívá a tedy ani nezabírá.

Aha, ok. Takže se můžeme spolehnout na to, že framework používá jen proměnné s podtržitkem? (_presenter, _control) a že pokud by to vyžadoval framework, tak si zavede svůj _user?

I když stále to neřeší to, že ve výpisu uživatelů, nebo na jeho detailu (což je skoro v každém projektu) nemohu použít

{foreach $users as $user} ... {/foreach}

ani přiřadit v presenteru $this->template->user, aniž bych tím neporušil defaultní chování, se kterým mohou ostatní programátoři počítat. Teoreticky se to týká všech „obsazených“ proměnných, ale u těch ostatních jsem ještě nikdy nenarazil na kolizi (control, presenter, netteHttpResponse, netteCacheStorage, baseUri, basePath, flashes a ten user).

@DavidGrudl: Jak to řešíš třeba na výpisu uživatelů, nebo na detailu uživatele? Přepíšeš tu defaultní proměnnou, nebo používáš něco jako $myUser, což mi přijde ošklivé řešení? Nebo doporučuješ úplně jinou cestu? V tomhle jsem si zatím nedokázal najít best practise, se kterým bych byl spokojený.

David Grudl
Nette Core | 8228
+
0
-

Co vím, tak používá jen podtržítkové proměnné a netteCacheStorage.

{foreach ... as $user} jsem asi nikdy nepoužil.

Jiří Nápravník
Člen | 710
+
0
-

Jo $this->template->user mi drive celkem zavařoval, nez mi to doslo…

CZechBoY
Člen | 3608
+
+1
-

Předávání User do šablony.
https://api.nette.org/…ory.php.html#90

Šaman
Člen | 2665
+
0
-

CZechBoY napsal(a):

Předávání User do šablony.
https://api.nette.org/…ory.php.html#90

Jestli to je odpověď na Davidovo „Framework ji nepoužívá a tedy ani nezabírá.“, tak on asi opravdu mluví jen o nepoužívání. Tedy, pokud si toho usera přepíšu, tak framework bude fungovat dál. Problém nastane, pokud někde dál budu třeba testovat, zda je $user->isLoggedIn(), ale to už je tak trochu moje chyba.

Ale stejně na to opakovaně narážím. Vzhledem k sandboxu/web-projectu a veškeré dokumentaci nechci tu proměnnou přepisovat (většina programátorů s ní počítá a většinou si myslí i že je to nativní chování Nette) – kdybych ji přepsal, zadělal bych na big WTF. A pokud zároveň pracuji třeba s pravou entitou User, tak pro ni musím vymýšlet zvláštní jméno a stejně pak často omylem napíšu $this->user a myslím tím tu entitu.

Oli
Člen | 1215
+
0
-

Taky me ten $user jednou nepekne potrapil. Mozna by nette mohlo hazet nejakej warning pri {var $user|$presenter|$control = 'foo'} a {foreach $foo as $user}? Tohle asi nikdo nechce schvalne prepsat…

ic
Člen | 430
+
+1
-

Začal jsem používat pojmenování proměnných tvořených foreachem jako $item. A postupem času si na to docela zvykl. Nebylo to z důvodu vyhnutí se problému s náhodným přejmenováním nějaké proměnné, ale prostě z lenosti, když mi to IDE ten cyklus takto napovídá, tak to použiji a s přejmenováváním si už hlavu nedělám :) . Pak vím, že mám v tom cyklu $iterator a $item a je to takové … všude pěkně stejné.

{foreach $foo as $item}
.
.
.

Problém jedině, když je třeba více vnořených cyklů, což ale není zase tak často… pak si to tedy pojmenuji nějak hezky.

Pavel Kravčík
Člen | 1196
+
+3
-
{if $article}
    <div class="page-header">
        <h1 n:block="title">{$article->title}</h1>
        {<small>{$article->date|date:'d.m.Y'}</small>}
    </div>
    <div class="perex">
        {$article->perex}
    </div>

    <div class="text">
        {$article->text}
    </div>
{else}
    Hlavní článek není zadán
{/if}

Pěkná chvilka, když n:block ignoruje if. :)

Editoval Pavel Kravčík (6. 12. 2015 22:20)

fizzy
Backer | 49
+
+1
-

Omylom som v sablone pouzil chybny znak pre pomlcku: –> namiesto → a debugger ma presviedcal, ze mi chyba metoda :D

Michal Hlávka
Člen | 190
+
0
-

Latte – pokud přistupuju k sloupci v databázi, který nabývá hodnoty null, sloupec neexistuje a vyhodí vyjímku

Eda
Backer | 220
+
+2
-

Právě jsem se dost zasekl na jedné věci a vzpomněl jsem si na tohle vlákno, tak třeba s tím půjde něco udělat :-)

Jde o použití generované továrny, která má metodu create s jedním parametrem, který pak má předat do konstruktoru vytvářené komponenty.

config.neon:

catalogSearchRendererControlFactory: ICatalogSearchRendererControlFactory

Interface pro továrnu:

interface ICatalogSearchRendererControlFactory extends IRendererFactory
{
    /**
     * @param SearchResult $searchResult
     * @return CatalogSearchRendererControl
     */
    public function create(SearchResult $searchResult);
}

Komponenta:

class CatalogSearchRendererControl extends AbstractControl
{
    /**
     * @param SearchResult $result
     */
    public function __construct(SearchResult $result)
    {
		...
    }
}

Když takový kód spustím, dostanu od laděnky nadělení v podobě chyby:
`Nette\DI\ServiceCreationException:
Service ‚catalogSearchRendererControlFactory‘: Service of type SearchResult needed by CatalogSearchRendererControl::__construct() not found. Did you register it in configuration file?`

Chyba je samozřejmě v tom, že název proměnné v rozhraní pro továrnu neodpovídá názvu parametru v konstruktoru, takže Nette si to „nematchne“, a tak se snaží ten argument autowirovat. Samozřejmě ho ale nenajde, takže to spadne.

Ta hláška ale není moc návodná.

Všechno se to děje v compile-time. Nestálo by za to tam přidat nějaký check na podchycení těchto situací? Co dělal jsem si miniprůzkum a nejsem sám, kdo se na tom někdy zasekl.

Felix
Nette Core | 1245
+
0
-

Eda napsal(a):

Chyba je samozřejmě v tom, že název proměnné v rozhraní pro továrnu neodpovídá názvu parametru v konstruktoru, takže Nette si to „nematchne“, a tak se snaží ten argument autowirovat. Samozřejmě ho ale nenajde, takže to spadne.

Ta hláška ale není moc návodná.

Všechno se to děje v compile-time. Nestálo by za to tam přidat nějaký check na podchycení těchto situací? Co dělal jsem si miniprůzkum a nejsem sám, kdo se na tom někdy zasekl.

Nedavno se mi stala podobna chyba a netusil jsem cim to je.

U me to bylo klasickym form vs fomr.

interface FooControlFactory
{
    /**
     * @param Form $form
     * @return FooControl
     */
    public function create(Form $form);
}

class FooControl
{
    /**
     * @param Form $form
     */
    public function __construct(Form $fomr)
    {
    }
}
David Matějka
Moderator | 6445
+
+2
-

https://forum.nette.org/…ikace-modely

mohlo by tam byt explicitne napsano, ze konstruktor je private, hlaska Class App\Modules\SMSModule\Models\SMSModel used in service ‚SMSModel‘ not found or is not instantiable. svadi spise k tomu, ze budu hledat, proc to tu tridu nenaslo

David Grudl
Nette Core | 8228
+
0
-

Pošlete pull requesty.

Casper
Člen | 253
+
+2
-

Issue už tady bylo před rokem, zajímavý je komentář od enumaga.

Editoval Casper (1. 3. 2016 10:13)

Eda
Backer | 220
+
+2
-

@DavidGrudl zkusil jsem to :-)

https://github.com/…e/di/pull/99

CZechBoY
Člen | 3608
+
+3
-

Tak jsem zjistil další zajímavost a to při přidávání routy.

$router[] = new Route('<presenter>/<action>[/<id]');

Všimne si někdo chyby, kvůli které Nette vygeneruje url např. /homepage/default?id=1, místo očekávaného /homepage/default/1?

Ano, chybějící zobáček „>“ za to může.

Michal Hlávka
Člen | 190
+
0
-

Pokud filter metoda nic nevrací, vypíše se, že filter není definovaný, i když je a Nette ho zavolalo. Celou dobu koukám na to, proč není definovaný, ale pak jenom zjistím, že switch nemám v plném rozsahu a tudiž mi nic nevrací.

Croc
Člen | 270
+
0
-

emptywall napsal(a):

Latte – pokud přistupuju k sloupci v databázi, který nabývá hodnoty null, sloupec neexistuje a vyhodí vyjímku

Přesně, tohle mě taky dosti potrápilo… A né jednou…

David Grudl
Nette Core | 8228
+
0
-

Croc napsal(a):

emptywall napsal(a):

Latte – pokud přistupuju k sloupci v databázi, který nabývá hodnoty null, sloupec neexistuje a vyhodí vyjímku

Přesně, tohle mě taky dosti potrápilo… A né jednou…

Pokud má hodnotu NULL, vrátí NULL a nevyhazuje výjimky.

ali
Člen | 342
+
0
-

Davide, kdyz je filter zaveden pres config takto, tak ano

latte.latteFactory:
	setup:
		- addFilter(NULL, [App\Service\Filters(), loader])
class Filters
{
	public static function loader(string $filter)
	{
		return (method_exists(__CLASS__, $filter) ? call_user_func_array([__CLASS__, $filter], array_slice(func_get_args(), 1)) : NULL);
	}
David Grudl
Nette Core | 8228
+
0
-

Teď tomu nerozumím, míchají se tu sloupce v databázi s filtry v Latte.

Takže pokud má sloupec hodnotu NULL, databáze rozhodně nevyhodí výjimku, že sloupec neexistuje. Reaguji na https://forum.nette.org/…ekolik-hodin?p=2

ad Latte: pokud loader filtru vrací NULL, tak se zkusí další loader v pořadí, což je příčina https://forum.nette.org/…ekolik-hodin?p=2. Hraje tu roli názvosloví, nebavíme se o filtru, ale o loaderu, o návratové hodnotě loaderu. Sice je možné, aby loader vrátil hodnotu a ta se brala jako výsledek filtru, ale loader by měl především filtr načíst, tedy zavolat addFilter, třeba kvůli výkonnosti. A filtr klidně může vracet NULL.

Takže config bych upravil na:

	latte.latteFactory:
		setup:
			- addFilter(NULL, [Filters(@self), loader])

a loader na:

class Filters
{
	private $latte;

	public function __construct(Latte\Engine $latte)
	{
		$this->latte = $latte;
	}

    public function loader(string $filter)
    {
        if (method_exists(__CLASS__, $filter)) {
        	$this->latte->addFilter($filter, [__CLASS__, $filter]);
        }
    }
Michal Hlávka
Člen | 190
+
0
-

@DavidGrudl asi jsme se jenom nepochopili – http://i.imgur.com/Q27ompb.jpg

Edit: až teď mi dochází, že tu každej motá jedno téma s druhým.

Editoval emptywall (29. 6. 2016 13:03)

Michal Hlávka
Člen | 190
+
0
-

David Grudl napsal(a):

Croc napsal(a):

emptywall napsal(a):

Latte – pokud přistupuju k sloupci v databázi, který nabývá hodnoty null, sloupec neexistuje a vyhodí vyjímku

Přesně, tohle mě taky dosti potrápilo… A né jednou…

Pokud má hodnotu NULL, vrátí NULL a nevyhazuje výjimky.

Teď jsem to zkoušel a je to jak říkáš. Už si přesně nepamatuju jak se mi to v té době povedlo, ale vím, že to tak bylo. Zkusím to příště víc rozepsat co pro to všechno člověk musí udělat. :-)