Diskuze: Pripojenie komponenty k DB

PHP Nette Framework Nette framework Pripojenie komponenty k DB

Avatar
Dominik Gavrecký:

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. května 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
Tým ITnetwork
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:

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

 
Nahoru Odpovědět 24. května 0:34
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:

Takze klasicky cez konstruktor ako v presenteri ?

Nahoru Odpovědět 24. května 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
Tým ITnetwork
Avatar
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:
<?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. května 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
Tým ITnetwork
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:

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. května 13:52
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:

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. května 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
Tým ITnetwork
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:

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. května 16:25
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:

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. května 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ý:

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. května 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
Tým ITnetwork
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:

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. května 16:57
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:

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

Nahoru Odpovědět  +1 24. května 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
Tým ITnetwork
Avatar
Odpovídá na Dominik Gavrecký
Jindřich Máca:

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í
+1 bodů
Řešení problému
 
Nahoru Odpovědět 24. května 21:46
Avatar
Odpovídá na Jindřich Máca
Dominik Gavrecký:

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

Nahoru Odpovědět  +1 24. května 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:

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  +1 24. května 22:57
Člověk může dosáhnout čeho si zamane. Jen musí chtít, případně něco obětovat ...
Avatar
Nahoru Odpovědět  +1 24. května 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.