Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Dominik Gavrecký:24.5.2016 0:23

Ahojte Ajťaci,

chcel by som sa vás spýtať ako riešite pripojenie komponenty k modelu. Neviem na to prísť už niekoľko dní a už som z toho mimo.

Ďakujem vám za každú radu

Odpovědět
24.5.2016 0:23
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 0:34

Ahoj, jednoduše si závislost na modelu předám pomocí DI. :D

 
Nahoru Odpovědět
24.5.2016 0:34
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 0:40

Takze klasicky cez konstruktor ako v presenteri ?

Nahoru Odpovědět
24.5.2016 0:40
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 0:49

Klidně může být. ;)

 
Nahoru Odpovědět
24.5.2016 0:49
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 13:29
<?php
/**
 * Created by PhpStorm.
 * User: Dominik Gavrecký
 * Date: 22.05.2016
 * Time: 19:26
 */

namespace Nette\Forms\Controls;

use Nette\Application\UI\Control;
use App\Model\NewsManager;

class Category extends Control
{
    /** @var newsManager*/
    public $newsManager;

    /**
     * Category constructor.
     * @param newsManager $newsManager
     */
    public function __construct(newsManager $newsManager)
    {
        parent::__construct();
        $this->newsManager = $newsManager;
    }


    public function renderCategory($id){
        $this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
        $this->template->news = $this->newsManager->getNews();
        $this->template->setFile(__DIR__ . '/name.latte');
        $this->template->render();
    }

}

Takto som to skúsil spraviť ale nabehne mi error.

Argument 1 passed to Nette\Forms\Controls\Category::__construct() must be an instance of App\Model\NewsManager, none given, called in /web/htdocs3/rewizeu/home/subdoms/dev/app/AdminModule/presenters/NewsPresenter.php on line 146
Nahoru Odpovědět
24.5.2016 13:29
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 13:52

Ahoj, mám k tomu hned několik věcí. 8-)

  1. Máš tam rozházená malá a velká písmena... :D
// Podle tohoto namespace, se ta třída jmenuje "NewsManager".
use App\Model\NewsManager;

// Potom ale dodržuj ten správný název s velkými písmeny.

    /** @var NewsManager*/
    public $newsManager;

    /**
     * Category constructor.
     * @param NewsManager $newsManager
     */
    public function __construct(NewsManager $newsManager)
    {
        parent::__construct();
        $this->newsManager = $newsManager;
    }
  1. Máš ten model dobře zaregistrovaný v konfiguračním souboru?
  2. Máš ten název a namespace dobře napsaný i v definici té třídy NewsManager?

Tohle si nejdříve vyřeš a potom se uvidí. :P

 
Nahoru Odpovědět
24.5.2016 13:52
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 14:42

Teraz by to malo byť správne. Registrovaný aj správne napísaný ten namespace je presne rovnakým spôsobom ako sa ho snažím využiť v komponente ho využívam aj v presenteri s tým rozdielom že v presenteri mi to funguje.

<?php
/**
 * Created by PhpStorm.
 * User: Dominik Gavrecký
 * Date: 22.05.2016
 * Time: 19:26
 */

namespace Nette\Forms\Controls;

use Nette\Application\UI\Control;
use App\Model\NewsManager;

class Category extends Control
{
    /** @var NewsManager */
    public $newsManager;

    /**
     * Category constructor.
     * @param NewsManager $newsManager
     */
    public function __construct(NewsManager $newsManager)
    {
        parent::__construct();
        $this->newsManager = $newsManager;
    }

    /**
     * @param $id
     * Render Category a jeho vykreslenie do name.latte
     */
    public function renderCategory($id){
        $this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
        $this->template->news = $this->newsManager->getNews();
        $this->template->setFile(__DIR__ . '/name.latte');
        $this->template->render();
    }

}
Nahoru Odpovědět
24.5.2016 14:42
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 16:25

No, tak ještě jedna technická připomínka, které jsem si před tím nevšiml, ale také by neměla mít vliv na funkčnost...

// Ten atribut by měl být spíš private.
/** @var NewsManager */
private $newsManager;

A potom si promaž cache i log a podívej se, jestli to pořád hází tu samou chybu nebo třeba nějakou jinou? :D

A pokud je to ta samá, tak sem ještě pošli, jak inicializuješ tu komponentu Category v rámci presenteru, ve kterém ji používáš. Mám takový pocit, že chyba bude nejspíše tam. :)

 
Nahoru Odpovědět
24.5.2016 16:25
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 16:42

Toto mám v presenteri s tým že som ten controler premenoval a cache som zmazal a namespace mám správny

protected function createComponentCategory()
   {
       $control= new NewsComponent;
       return $control;
   }
Nahoru Odpovědět
24.5.2016 16:42
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 16:45

Pre istotu tu dám aj upravený controler

<?php
/**
 * Created by PhpStorm.
 * User: Dominik Gavrecký
 * Date: 22.05.2016
 * Time: 19:26
 */

namespace Nette\Forms\Controls;

use Nette\Application\UI\Control;
use App\Model\NewsManager;

class NewsComponent extends Control
{
    /** @var NewsManager */
    private $newsManager;

    /**
     * Category constructor.
     * @param NewsManager $newsManager
     */
    public function __construct(NewsManager $newsManager)
    {
        parent::__construct();
        $this->newsManager = $newsManager;
    }

    /**
     * @param $id
     * Render Category a jeho vykreslenie do name.latte
     */
    public function renderCategory($id){
        $this->template->categoryName = $this->newsManager->getCategory()->where('id', $id);
        $this->template->news = $this->newsManager->getNews();
        $this->template->setFile(__DIR__ . '/name.latte');
        $this->template->render();
    }

}
Nahoru Odpovědět
24.5.2016 16:45
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 16:57

Tak pak je to úplně jasné... :D

protected function createComponentCategory()
{
       $control= new NewsComponent; // TOHLE JE ŠPATNĚ!*
       return $control;
}

* Pokud totiž instanciuješ komponentu tímto způsobem, pomocí new, musíš se o předání závislostí v konstruktoru postarat sám. Druhým způsobem je pak používání továrniček, kde se o dodání závislostí stará Nette samo, pomocí DI. Tohle vše je popsané v mém seriálu o Nette. :P

 
Nahoru Odpovědět
24.5.2016 16:57
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 17:33

Ako to myslis sám mohol by si mi poskytnúť nejaký názorný príklad ?

Nahoru Odpovědět
24.5.2016 17:33
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:24.5.2016 21:46

No dobrá, tak že jsi to ty.

  1. Předání závislostí v konstruktoru. Tohle by jsi měl bezpečně znát, protože to patří do základů OOP.
// Uvnitř daného presenteru.

 /** @var NewsManager */
private $newsManager;

/**
 * Presenter constructor.
 * @param NewsManager $newsManager
 */
public function __construct(NewsManager $newsManager)
{
    parent::__construct();
    $this->newsManager = $newsManager;
}

protected function createComponentCategory()
{
    /* Předáváš závislost v konstruktoru,
       přičemž tu předávanou instanci musíš samozřejmě někde získat,
       v tomto případě pomocí DI v rámci daného presenteru. */
    $control= new NewsComponent($this->newsManager);
    return $control;
}
  1. Automatické předání závislosti pomocí DI za použití továrničky pro danou komponentu Category. Jelikož Nette navíc umožňuje vytvářet generované továrničky s autowiringem, tak je dobré toho využít. Tohle už je samozřejmě pokročilá technika z Nette, takže bližší info najdeš třeba tady - https://pla.nette.org/…h-autowiring
// Uvnitř souboru s třídou komponenty *Category* přidáme ještě interface.
class Category extends Control
{
    ...
}

interface ICategoryFactory
{
        /**
         *
         * @return Category
         */
        public function create();
}

// Ten pak musíme zaregistrovat jako službu továrničky v konfiguračním souboru.
services:
        - Nette\Forms\Controls\ICategoryFactory

// A dále tuto továrničku získáme v presenteru pomocí DI a použijeme pro tvorbu komponenty.

// Uvnitř daného presenteru.

     /** @var ICategoryFactory */
    private $categoryFactory;

    /**
     * Presenter constructor.
     * @param ICategoryFactory $categoryFactory
     */
    public function __construct(ICategoryFactory $categoryFactory)
    {
        parent::__construct();
        $this->categoryFactory = $categoryFactory;
    }

    protected function createComponentCategory()
    {
        // Instance se prostě vytvoří a o všechny její závislosti je postaráno automaticky.
        $control= $this->categoryFactory->create();
        return $control;
    }

Tak si myslím, že víc názornější už jsem snad být nemohl. :D Máš k tomu ještě nějaké otázky?

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
24.5.2016 21:46
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:24.5.2016 21:47

Ďakujem ti vážne si to od teba strašne vážim :)

Nahoru Odpovědět
24.5.2016 21:47
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Avatar
TomasGlawaty
Člen
Avatar
Odpovídá na Dominik Gavrecký
TomasGlawaty:24.5.2016 22:57

Dodal bych jen takové detaily. Pro vlastní komponenty nepoužívej namespace Nette\Forms\Con­trols ale nejaky vlastní, tohle platí pro všechny třídy. Proste to nedává smysl, jelikož ta tvoje komponenta neni součásti Nette :) dále v konstruktoru potomka UI\Control neni potřeba volat předkuv kontruktor, jelikož by mel byt volný.

 
Nahoru Odpovědět
24.5.2016 22:57
Avatar
Odpovídá na TomasGlawaty
Dominik Gavrecký:24.5.2016 23:40

Ďakujem dám si na to pozor :)

Nahoru Odpovědět
24.5.2016 23:40
Hlupák nie je ten kto niečo nevie, hlupákom sa stávaš v momente keď sa na to bojíš opýtať.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 16 zpráv z 16.