Link odkazem a následným vyčtením z databáze
- milde
- Člen | 52
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??
- milde
- Člen | 52
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
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
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..
- milde
- Člen | 52
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.
- milde
- Člen | 52
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
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.
- milde
- Člen | 52
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 :-(
- milde
- Člen | 52
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
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
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
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
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ě ;) )
- VaKvas
- Začátečník | 111
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
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í?