Co mam zle? Multiple services

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

Ahojte, tak znova sa na vás musím obrátiť s prosbou o pomoc :P … chcem v jednej šablóne vykresliť jednu tabuľku z DB viac krát. Najskor sa mi vypíšu veci s ID číslo 1, potom v ďalšom boxe v tej istej šablóne z rovnakej tabuľky veci s ID = 2… a tak ďalej. Používam webchemistry/cms kde je už raz táto vec spravená a funguje, no keď som si vytvoril ďalšiu svoju tak tam mám nejaký problém ale neviem ho nájsť…

Chybová hláška:
Service ‚application.4‘: Multiple services of type App\UserModule\Components\DanGrid found: 117_App_UserModule_Components_Dan2Grid, 119_App_UserModule_Components_DanGrid

Kód v DanGrid.php:

<?php

class DanGrid extends BaseControl {

	/** @var string For Dan2 */
	protected $danSelect = 'partial a.{id, vyber, nazov1, sadzba}';

	/**
	 * @return Grid
	 */
	public function createGrid() {
		$grid = $this->getGrid();

		$grid->setDataSource(
			$this->em->getRepository(\Entity\Dan::class)
				->createQueryBuilder('a')
				->select($this->danSelect)
				->where('a.vyber = 1')

		);

		$grid->addColumnText('nazov1', 'user.admin.grid.nazov1');
			//->setSortable();
		$grid->addColumnText('sadzba', 'user.admin.grid.sadzba');
			//->setSortable();





		return $grid;
	}

}

Kód v Dan2Grid.php:

class Dan2Grid extends DanGrid {

	/**
	 * @return Grid
	 */
	public function createGrid() {
		$grid = parent::createGrid();

		$grid->setDataSource(
			$this->em->getRepository('Entity\Dan')
				->createQueryBuilder('a')
				->select($this->danSelect)
				->where('a.vyber = 2')

		);

		return $grid;
	}

}

Presenter:

class DanPresenter extends AdminPresenter {

	/** @var Components\DanForm */
	public $danForm;

	/** @var Components\RoleForm */
	public $roleForm;

	/** @var Components\DanGrid */
	public $danGrid;

	/** @var Components\Dan2Grid */
	public $dan2Grid;

	/** @var Components\IUserAdminGrid */
	public $adminGrid;

	/** @var Components\RoleGrid */
	public $roleGrid;

	/** @var Configuration */
	private $configuration;

	/**
	 * @param Configuration $configuration
	 * @param Components\DanForm $danForm
	 * @param Components\RoleForm $roleForm
	 * @param Components\DanGrid $danGrid
	 * @param Components\Dan2Grid $dan2Grid
	 * @param Components\IUserAdminGrid $adminGrid
	 * @param Components\RoleGrid $roleGrid
	 */
	public function __construct(Configuration $configuration, Components\DanForm $danForm,
								Components\RoleForm $roleForm, Components\DanGrid $danGrid, Components\Dan2Grid $dan2Grid,
								Components\IUserAdminGrid $adminGrid, Components\RoleGrid $roleGrid) {
		$this->configuration = $configuration;
		$this->danForm = $danForm;
		$this->roleForm = $roleForm;
		$this->danGrid = $danGrid;
		$this->dan2Grid = $dan2Grid;
		$this->adminGrid = $adminGrid;
		$this->roleGrid = $roleGrid;
	}

	/************************* Default **************************/

	/**
	 * @return Form
	 */
	protected function createComponentDanRegistration() {
		$form = $this->danForm->createDan();

		$form->onSuccess[] = $this->successDanRegistration;

		return $form;
	}

	/**
	 * @param Form $form
	 * @param ArrayHash $values
	 */
	public function successDanRegistration(Form $form, $values) {
		$this->createNotification('user.admin.notifications.adddan', UserSettings::ICON, $values->nazov1);

		$this->flashMessage('user.admin.flashes.adddan');
		$this->redraw();
	}

	/**
	 * @return Components\DanGrid
	 */
	protected function createComponentDanGrid() {
		return $this->danGrid->createGrid();
	}

	/**
	 * @return Components\Dan2Grid
	 */
	protected function createComponentDan2Grid() {
		return $this->dan2Grid->create()->createGrid();
	}



	/**
	 * @return Components\UserGridAdmin
	 */
	protected function createComponentAdminGrid() {
		return $this->adminGrid->create()->createGrid();
	}

Editoval marcelJP2 (17. 4. 2016 14:19)

ViPEr*CZ*
Člen | 818
+
0
-

Problém je někde v konfiguračním neonu podle chyby a duplikuje se tam konkrétně ta služba, o které se v té chybě mluví. Když tak postněte jak vypadá ještě onen neon.

CZechBoY
Člen | 3608
+
0
-

Lepsi udelat tovarnicku, takhle vyzadovat komponentu neni dobry.

edit: aha, ty máš nějakou pseudo-komponento-továrnu…
Tak nedělej 2 stejné továrny, ale ten datasource nastavuj až v createComponentXXX (jak píše @Šaman podemnou).

Editoval CZechBoY (17. 4. 2016 15:33)

Šaman
Člen | 2666
+
0
-

V configu ji máš dvakrát (nebo nějakého jejího potomka) a když si ji pak vyžádáš, tak DI kontejner neví, kterou má předat.


Edit: Taky že jo, z kódu je vidět, že máš DanGrid a pak DanGrid2, který je ale také instanceof DanGrid. Takže když si pak někde vyžádáš DanGrid, pak není jednoznačné, který vlastně chceš (z pohledu OOP jsou obě třídy DanGrid, stejně jako jsou bě BaseControl).

Jak psal CZechBoY, tohle se řeší továrničkou, to setDataSource() dej až do createComponentDanGrid() a createComponentDan2Grid().

Editoval Šaman (17. 4. 2016 15:23)

marcelJP2
Člen | 19
+
0
-

takze by to malo vyzerat nejako takto?

Presenter:

	/**
	 * @return Components\DanGrid
	 */
	protected function createComponentDanGrid() {
		return $this->danGrid->createGrid();

		$grid->setDataSource(
			$this->em->getRepository(\Entity\Dan::class)
				->createQueryBuilder('a')
				->select($this->danSelect)
				->where('a.vyber = 1')

		);
	}

	/**
	 * @return Components\Dan2Grid
	 */
	protected function createComponentDan2Grid() {
		return $this->dan2Grid->create()->createGrid();

	$grid->setDataSource(
		$this->em->getRepository('Entity\Dan')
			->createQueryBuilder('a')
			->select($this->danSelect)
			->where('a.vyber = 2')

	);
	}

DanGrid.php:

class DanGrid extends BaseControl {

	/** @var string For Dan2 */
	protected $danSelect = 'partial a.{id, vyber, nazov1, sadzba}';

	/**
	 * @return Grid
	 */
	public function createGrid() {
		$grid = $this->getGrid();

		$grid->addColumnText('nazov1', 'user.admin.grid.nazov1');
			//->setSortable();
		$grid->addColumnText('sadzba', 'user.admin.grid.sadzba');
			//->setSortable();

		return $grid;
	}

aaa **Dan2Grid.php: **

class Dan2Grid extends DanGrid {

	/**
	 * @return Grid
	 */
	public function createGrid() {
		$grid = parent::createGrid();


		return $grid;
	}

}
marcelJP2
Člen | 19
+
0
-

ešte som skúsil jednu vec, v config.neon som mal registrované:

  • App\UserModule\Components\DanGrid
  • App\UserModule\Components\Dan2Grid

nechal som kód rovnako ako mám uvedené v úplne prvom príspevku a potom som spravil nasledovne:

ak som odstránil Dan2Grid tak mi napísalo že či mám túto službu registrovanú v konfigu? ale ak som odstránil DanGrid… tak sa mi to celé spustilo, nepotrebovalo mať DanGrid registrované v konfigu no zároveň sa mi na stránke zobrazujú dáta iba podľa toho ako ich mám nastavené v Dan2Grid. Ako keby DanGrid ostalo ignorované…

cize z DaGrid.php

public function createGrid() {
		$grid = $this->getGrid();

		$grid->setDataSource(
			$this->em->getRepository(\Entity\Dan::class)
				->createQueryBuilder('a')
				->select($this->danSelect)
				->where('a.vyber = 1')

		);

mi toto vobec neberie… tvari sa ako by to tam nebolo. Logicky ak nemam v konfigu zapnute DanGrid.php tak jasne… tuto sluzbu neregistruje… lenze ak zapnem tak som znova na tom multiservices

Editoval marcelJP2 (17. 4. 2016 16:29)

CZechBoY
Člen | 3608
+
+1
-

To uz ti prece psal Saman… DanGrid2 dedi DanGrid.

Pouzij tu variantu z predpredchoziho kodu a vyhod ten DanGrid2 (je uplne stejnej jako DanGrid).
Potom v createComponentXXX mas return a az potom nastavujes promennou… Na konec te metody dej return, jinak se ti nic nenastavi (return konci provadeni funkce).

Editoval CZechBoY (17. 4. 2016 16:39)

Martk
Člen | 661
+
0
-

Vím, že to neřeší tvůj problém, ale není lepší udělat tohle, protože ty gridy hodně souvisí?

class DanGrid extends BaseControl {

    /** @var string For Dan2 */
    protected $danSelect = 'partial a.{id, vyber, nazov1, sadzba}';

    /**
     * @return Grid
     */
    private function baseGrid($vyber) {
        $grid = $this->getGrid();

        $grid->setDataSource(
            $this->em->getRepository(\Entity\Dan::class)
                ->createQueryBuilder('a')
                ->select($this->danSelect)
                ->where('a.vyber = :vyber')
				->setParameter('vyber', $vyber)

        );

        $grid->addColumnText('nazov1', 'user.admin.grid.nazov1');
            //->setSortable();
        $grid->addColumnText('sadzba', 'user.admin.grid.sadzba');
            //->setSortable();

        return $grid;
    }

	/**
     * @return Grid
     */
    public function createGrid() {
        return $this->baseGrid(1);
    }

	/**
     * @return Grid
     */
    public function createGrid2() {
        return $this->baseGrid(2);
    }

}

Editoval Antik (18. 4. 2016 21:49)