Link odkazem a následným vyčtením z databáze

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

Zdravím všechny borce přes Nette. Řeším jeden poblém a nikde jsem na fóru nenašel nic co by mě pomohlo nakopnout. Jde o to, že geneuji menu, přes javascript ( rozklikávací menu ) a po rozkliknutí se mi zobrazi několik položek – konkrétně týdnů. V klasickém php jsem k načtení dat z databáze používal jednoduchý trik: do linku jsem schoval id a dotazem jsme vydoloval data

<?php
<a href="neco.php?x=1>neco</a>
//pak nasledoval dotaz na databazi
?>

Ale v tomto pripade nevim, jak to v nette udělat. Poradíte mi, prosim někdo??

VaKvas
Začátečník | 111
+
0
-

A jde ti ted o co? Jak udelat link v sablone nebo jak se pripojit k databazi ci jak udelat metodu, ktera vrati pozadovana data ? ......

Zkus byt konkretnejsi…

milde
Člen | 52
+
0
-

VaKvas napsal(a):

A jde ti ted o co? Jak udelat link v sablone nebo jak se pripojit k databazi ci jak udelat metodu, ktera vrati pozadovana data ? ......

Zkus byt konkretnejsi…

Rozumím. V šabloně mám následující kód:

<?php
<a href=./  onClick="processTree (0); return false;">3. - 12 tyden</a>
  {for $i=3;$i<=12;$i++}
    <div id="sub_0_{$i}" class="SubItemRow">
	<a href="tyden">{$i}. tyden</a>
    </div>
  {/for}
?>

Dříve bych to řešil tak, jak jsem psal výše.
Navíc se přiznám, že si nevím rady ani s tou metodou. Něco jsem tu našel, ale nevím, jak to implementovat ( je mi tepve 17, tak se to učím, poto prosím o schovívavost ). Takže v modelu mám tuto funkci:

<?php
class VypisTyden {
	public static function fetchAll(){
		return dibi::fetchAll('SELECT * FROM [tyden] WHERE [id_tyden] = %i', $id_tyden);
	}
}
?>

a v presenteru:

<?php
class TydenPresenter extends BasePresenter
{
	public function renderDefault()
	{
		$this->template-> posts = VypisTyden::fetchAll();
	}
}
?>
Ot@s
Backer | 476
+
0
-

Koukni na odkazy v šablonách.
Důležité je, abys věděl, kam vlastně chceš odkaz směrovat (presenter/akce/handler)…

VaKvas
Začátečník | 111
+
0
-

Mas v tom nejaky binec ;)

Tak treba:

MODEL:

class TydenModel extends BaseModel {

	function __construct() {
		$this->data = $database->table('tyden');
    	}

	function getDataById($id) {
	    	$this->data->where('id', $d);
	    	return $this->data;
	}
}

PRESENTER

class TydenPresenter extends BasePresenter {
	public function renderDefault() {
		$this->template->posts = $this->TydenModel->getDataById($id); //musis zajistit spravne volani modelu. Napr. pres modelLoader
	}
}

A SABLONA

<a n:href="Tyden: id=>$id">Tyden xy</a>

samozrejme se musis postarat o napriklad ziskavani parametru pres id v presenteru, pak o pristupnost modelu v presenteru (ModelLoader, ktery si nastavis napr. v BasePresenteru), a o to aby existovala patricna sablona, presenter a model.

Ale pokud zacnes tady , tak tim nic nezkazis..

22
Člen | 1478
+
0
-

btw $id se předává automaticky, tedy stačí:

<a n:href="Tyden: $id">Tyden xy</a>

Editoval 22 (30. 8. 2011 14:44)

milde
Člen | 52
+
0
-

VaKvas napsal(a):

Mas v tom nejaky binec ;)

To mám, snažím se to pochopit a naučit

samozrejme se musis postarat o napriklad ziskavani parametru pres id v presenteru, pak o pristupnost modelu v presenteru (ModelLoader, ktery si nastavis napr. v BasePresenteru), a o to aby existovala patricna sablona, presenter a model.

Moc nerozumím tomu nastavení ModelLoaderu v BasePresenteru

Ale pokud zacnes tady , tak tim nic nezkazis..

Na to jsem se koukal, ale jestli jsem to spravně pochopil, tak je to vše taháno z databáze, ale to menu, co mám já, tak se volá „přímo“ ze šablony a po klinutí na týden by se právě obsah další stránky měl tahat z batabáze.
Jsem proste začátečnická lama, tak prosím o trpělivost s mými možná triviálními dotazy.

VaKvas
Začátečník | 111
+
0
-

Jeste koukni sem na MVC

milde
Člen | 52
+
0
-

VaKvas napsal(a):

Jeste koukni sem na MVC

Tak jsem se dva dny prokousával radami a jediné čeho jsem docílil je hlášení laděnky: Cannot read an undeclared property HomepagePresenter::$TydenModel
Neví tu někdo v čem je problém a popříbadě byl by někdo ochotný mi alespoň nastínit jak dál? Za každou radu jsem moc vděčný – jsem holt začátečnická lama. Předem moc děkuji.

Editoval milde (1. 9. 2011 13:00)

mkoubik
Člen | 728
+
0
-

Zaregistruj si model jako službu. Pokud používáš dibi staticky, tak by mělo stačit dát do config.neon

services:
	tydenModel:
		class: TydenModel

a pak v presenteru $this->template->posts = $this->context->TydenModel->getDataById($id);.
Ale stejně si skus tady na fóru vyhledat „model loader“ a předělat to pak podle toho.

VaKvas
Začátečník | 111
+
0
-

Mozna na pochopeni bude snazsi pokud si da do BasePresenteru:

public $tydenModel;

    function startup() {
	parent::startup();

	$this->tydenModel = new TydenModel;

}
milde
Člen | 52
+
0
-

VaKvas napsal(a):

Mozna na pochopeni bude snazsi pokud si da do BasePresenteru:

public $tydenModel;

    function startup() {
	parent::startup();

	$this->tydenModel = new TydenModel;

}

ahoj, děkuji za radu, hned jsem to zkusil a hlasí mi to že třída TydenModel neexistuje ( v BasePesenteru ) přitom v modelech ji mám … já snad nette nikdy nepochopím :-(

VaKvas
Začátečník | 111
+
0
-

Nemas tam nejaky namespace?
Posli sem, jak to ted mas…

milde
Člen | 52
+
0
-

VaKvas napsal(a):

Nemas tam nejaky namespace?
Posli sem, jak to ted mas…

ted mám BasePresenter:

<?php
abstract class BasePresenter extends Nette\Application\UI\Presenter{
	public $TydenModel;
	public function startup(){
		parent::startup();
		$this -> TydenModel = new TydenModel;
	}
	public function beforeRender(){ }
?>

TydenModel:

<?php
namespace Model;
use Nette\Object,
	Nette\Enviroment,
	Nette\Database\Connection;


class TydenModel extends BaseModels{
	function __construct(){
		$this -> data = $database -> table('tyden');
	}
	function getDataById($id){
		$this -> data -> where('id', $d);
		return $this->data;
	}
}
?>

a šablona:

<?php
{for $i=1;$i<=13;$i++}
	<div id="sub_0_{$i}" class="SubItemRow">
		<a n:href="tyden $id=$i">{$i}. tyden</a>
	</div>
{/for}
?>
VaKvas
Začátečník | 111
+
0
-
$this -> tydenModel = new Model\TydenModel;

Editoval VaKvas (1. 9. 2011 14:14)

milde
Člen | 52
+
0
-

VaKvas napsal(a):

$this -> tydenModel = new Model\TydenModel;

díky za tvou trpělivost – toto řešení pomohlo, už to alespoň hlásí jinou chybu – nedefinovaná proměnná databáze v TydenModelu – tak se jdu tím zkusit prokousat dále …

VaKvas
Začátečník | 111
+
0
-

To si zas muzes udelat v baseModelu napr:

static public $database;

    static function init($database) {
	self::$database = new \Nette\Database\Connection(
			$database->dsn, $database->user, $database->password);
}

kdy v configu by jsi mel pak mit neco jako:

database:
		dsn: 'mysql:host=localhost;dbname=dbname'
		user: user
		password: 'pass'

jo a nazvy promenych je lepsi zacinat malym ;)

milde
Člen | 52
+
0
-

VaKvas napsal(a):

To si zas muzes udelat v baseModelu napr: …

tak jsem to vyzkoušel a hlásí to stejný problém – jsem lama, ale nechci se na to vykašlat …
Pro jistotu přikladám jak vypadá můj BaseModel a neon …
BaseModel:

<?php

namespace Model;
use Nette\Object,
	Nette\Enviroment,
	Nette\Database\Connection;

class BaseModels extends Object{

	protected static $connection = null;
	public static  $database;
	public static function initialize(){

		$dbConfig = Environment::getConfig('database');
		self::$connection = new Connection("{$dbConfig->driver}:host={$dbConfig->host};dbname={$dbConfig->database}",$dbConfig->username,$dbConfig->password);
	}
	public static function init($database) {
        self::$database = new \Nette\Database\Connection($database->dsn, $database->user, $database->password);
	}

}
?>

a neon:

<?php
services:
		robotLoader:
			run: true

		database:
			class: Nette\Database\Connection
			arguments: ['mysql:host=localhost;dbname=pokus', 'root', '']

		model:
			class: Model
			arguments: [@database]

		authenticator:
			factory: [@model, createAuthenticatorService]


production < common:

development < common:
	database:
			driver: mysql
			host: localhost
			username: root
			password:
			database: pokus
			charset: utf8
			profiler: true
?>
VaKvas
Začátečník | 111
+
0
-

Mas tam v podstate 2× to same.. pokud vytvaris servis database tak :
Ja jsem uvedl priklad jako $database, ale mysleno bylo $connection ;) moje nepresnost

BaseModel (bez s) !

protected $database;

	public function __construct(Nette\Database\Connection $database)
	{
		$this->database = $database;
	}

a v samotnem modelu (napr. tydenModel) :

class TydenModel extends BaseModel
{
	public function __construct($database){
	    parent::__construct($database);
	}

	public function getData(...){
	    ...
	}
}
milde
Člen | 52
+
0
-

VaKvas napsal(a):

Mas tam v podstate 2× to same.. pokud vytvaris servis database tak :
Ja jsem uvedl priklad jako $database, ale mysleno bylo $connection ;) moje nepresnost

zkusil jsem to tak jak jsi mi poradil, nicméně hlasí to: Missing argument 1 for Model\TydenModel::__construct(), called in C:\xampp\htdocs\pokus_nette\sandbox\app\front\presenters\BasePresenter.php on line 15 and defined Přiznám se, že jsem z toho celej tumpachovej … a tobě děkuji za trpělivost. Má snaha se něco naučit se možná cení, ale já oceňuji tvou trpělivost a hlavně rady zkušeného. Díky za ty rady a pomoc ( možná se to nakonec bude hodit i nějaké jiné nezkušené lamě ;) )

Jan Endel
Člen | 1016
+
0
-

VaKvas napsal(a):

$this -> tydenModel = new Model\TydenModel;

Pokud chceš předávat databázi takhle tak to jednoduše uprav na:

	$this -> tydenModel = new Model\TydenModel($this->context->database);
VaKvas
Začátečník | 111
+
0
-

Pokud se jedna o reseni bez ModelLoaderu a bez database jako servisu :

CONFIG:

common:
	database:
		dsn: 'mysql:host=localhost;dbname=db_name'
		user: root
		password: 'heslo'

Do bootstrapu pridas:

$application->onStartup[] = function(){
    Namespace(pokud je)\BaseModel::init(Environment::getConfig()->database);
};

a pak v BaseModelu bude toto :

static public $database;

    static function init($database) {
	self::$database = new \Nette\Database\Connection(
			$database->dsn, $database->user, $database->password);
    }

a pak uz jen ten BasePresenter, ktery mas:

public $TydenModel;

function startup() {
	parent::startup();
	$this->tydenModel = new Model\TydenModel;
}

a v ostatnich modelech pristupujes k datum :

$this->tydenModel->getData();

Toto je jeste varianta s Environment, ale myslim, ze pro prvni kroky je to prehledne…

Editoval VaKvas (1. 9. 2011 16:51)

milde
Člen | 52
+
0
-

pilec napsal(a):

VaKvas napsal(a):

$this -> tydenModel = new Model\TydenModel;

Pokud chceš předávat databázi takhle tak to jednoduše uprav na:

	$this -> tydenModel = new Model\TydenModel($this->context->database);

Děkuji za cenné rady, ale furt to hlasí nějaké chyby … zeptám se tedy na rovinu, nevíte náhodou o nějakém tutoriálu, ze kterého by to bylo zřejmě a hlavně jednoduché na pochopení?

milde
Člen | 52
+
0
-

** VaKvas** … díky, zkusím se ještě podívat na tvé řešení a dám vědět jak jsem pochodil či nikoli …

VaKvas
Začátečník | 111
+
0
-

Kdyz ono se to vsechno toci prave kolem toho tutorialu v dokumentaci. Tam najdes ted uz uplne vse, co potrebujes na zacatek.