Pomoc začátečníkovi: chyba Call to a member function getElements() on a non-object
- bostiko
- Člen | 10
Dobrý den,
začal jsem s Nette před pár dny a nevím si rady. Vyskakuje na mě chyba
„Call to a member function getElements() on a non-object“. Mám verzi nette
0.9 s Namespace. Snažím se podle ní rozchodit variaci na řešení, které
David Grudl uvedl na PHPFashion pod názvem MVC paradox a jak jej řešit. Mým
cílem je vytáhnout z db obsah tabulky a předat ho šabloně jako pole, se
kterým si pohraji s pomocí Foreach.
Byl by někdo tak laskav a našel mi chybu? Díky předem…
PrintScreen Chyby na imageshack
Dále přikládám mé zdrojové kódy:
models/Elements.php
<?php
class Elements
{
function getElements()
{
return dibi::dataSource('Select * FROM [Elements]');
}
}
?>
presenters/DiskuzePresenter.php
<?php
class DiskuzePresenter extends BasePresenter
{
private $elements = NULL;
Public function renderDefault($page)
{
$this->elements->getElements();
$this->elements->where('Index=%b', True);
$this->template->xelements = $elements;
}
Public Function showDefault()
{
}
Public function getElements()
{
if (!isset($this->elements))
$this->elements = new Elements();
return $this->elements;
}
}
?>
templates/Diskuze/default.phtml
{block content}
{foreach $xelements->select(array('Typ', 'Nazev', 'Hodnota', 'Top', 'Left', 'V', 'S', 'T_P)) as $element}
Tady to jsem ještě nedodělal, ale kdyby to pracovalo správně, tak by to mělo vypsat tento text x-krát pod sebe...
{/foreach}
- bostiko
- Člen | 10
CZechBoY napsal(a):
nechápu jak můžeš z proměnný, která je null něco dostat..
že by chyběl nějaký soubor k přiložení?
- to jsem našel v podobném příkladu a má to nulový efekt. Tu samou chybu to hlásí ať je tam, nebo to zakomentuji.
- Nic by podle mého chybět nemělo, ale já odborník nejsem…
- bostiko
- Člen | 10
CZechBoY napsal(a):
<?php $this->elements->getElements(); $this->elements->where('Index=%b', True); $this->template->xelements = $elements; ?>
zkus změnit na
<?php $this->elements->where('Index=%b', True); $this->template->xelements = $this->elements; ?>
V tomto případě to hlásí chybu Call to a member function where() on a non-object, což je ve výsledku to samé…
- bostiko
- Člen | 10
smasty napsal(a):
Problém je v tom, že
Nette\Object
properties nefungujú z vnútra objektu. Nahraď volanie$this->elements
za$this->getElements()
a všetko bude v poriadku.
Krapet jsem to nepochopil. Který řádek mám přepsat tímto? Zkoušel jsem všechno možné ale nefunguje to. Dokonce se mi to nádherně zacyklilo…
- bostiko
- Člen | 10
22 napsal(a):
myslím, že mít metodu getElements() a proměnnou $this->elements je teda špatnej nápad, protože díky Nette\Object se při $this->elements volá getElements(). Jedno z toho bych přejmenoval.
Zkoušel jsem to, a nepomohlo to.
gmvasek napsal(a):
Jakýkoliv výskyt $this->elements nahraď za $this->getElements().
udělal jsem to, a hlásí to, že:
Can't use method return value in write context
a hlásí to řádek:
$this->getElements()->where(‚Index=%b‘, True);
případně, pokud to zakomentuji, tak to hlásí tento:
if (!isset($this->getElements()))
Pokud se vám už se mnou nechce otravovat, šlo by případně místo mého způsobu to udělat nějakým jiným způsobem? Nějakým jednodušším, ale abych zároveň využíval MVP?
- 22
- Člen | 1478
<?php
final class DiskuzePresenter extends BasePresenter
{
private $element = NULL;
public function renderDefault($page)
{
$data = $this->model->getElements();
$data = $data->where('Index=%b', True);
$this->template->xelements = $data;
}
public Function showDefault()
{
}
public function getModel()
{
if (!isset($this->element)) {
$this->element = new Elements();
}
return $this->element;
}
}
?>
Editoval 22 (23. 6. 2011 22:50)
- uestla
- Backer | 799
Ahoj!
Zkus nejprve přepsat
private $elements = NULL;
na
/** @var DibiDataSource */
private $elementsSource = NULL;
Hned potom uprav metodu getElements()
:
if ($this->elements === NULL) {
$els = new Elements();
$this->elements = $els->getElements();
}
return $this->elements;
Následně ještě uprav metodu renderDefault()
:
$this->elements->where('Index = %b', TRUE);
$this->template->xelements = $this->elements;
A nakonec se s námi poděl o tom, jak to dopadlo.
PS: Nepiš prosím počáteční písmenka u klíčových slov jazyka velká, působí to odpudivě ;-)
- bostiko
- Člen | 10
uestla napsal(a):
Ahoj!
Zkus nejprve přepsat
private $elements = NULL;
na
/** @var DibiDataSource */ private $elementsSource = NULL;
Hned potom uprav metodu
getElements()
:if ($this->elements === NULL) { $els = new Elements(); $this->elements = $els->getElements(); } return $this->elements;
Následně ještě uprav metodu
renderDefault()
:$this->elements->where('Index = %b', TRUE); $this->template->xelements = $this->elements;
A nakonec se s námi poděl o tom, jak to dopadlo.
PS: Nepiš prosím počáteční písmenka u klíčových slov jazyka velká, působí to odpudivě ;-)
Tento způsob nefunguje.
22 napsal(a):
<?php final class DiskuzePresenter extends BasePresenter { private $element = NULL; public function renderDefault($page) { $data = $this->model->getElements(); $data = $data->where('Index=%b', True); $this->template->xelements = $data; } public Function showDefault() { } public function getModel() { if (!isset($this->element)) { $this->element = new Elements(); } return $this->element; } } ?>
Ale tento ano.
Děkuji všem za pomoc a trpělivost.
Poslední věc. Nevíte, proč mi poté nefunguje latte? Když se to spustí,
stránka generuje:
{foreach $xelements->select(array(‚Typ‘, ‚Nazev‘, ‚Hodnota‘,
‚Top‘, ‚Left‘, ‚V‘, ‚S‘, 'T_P)) as $element} Text {/foreach}
- uestla
- Backer | 799
Tento způsob nefunguje.
Máš pravdu, správně měla být metoda getElements()
přepsána takto:
if ($this->elementsSource === NULL) {
$model = new Elements();
$this->elementsSource = $model->getElements();
}
return $this->elementsSource;
Pardon!
Proč ti nefunguje Latte netuším, chce to více detailů :-)
- uestla
- Backer | 799
Ajo :-D
Tak té jsem si nevšiml – to je tak, když tu lidé nezvýrazňují kód ;-)
Přitom na to je tlačítko :-(
Kdybys to udělal, přišel bys na to hned, koukej:
{foreach $xelements->select(array('Typ', 'Nazev', 'Hodnota', 'Top', 'Left', 'V', 'S', 'T_P)) as $element}
Text
{/foreach}
- bostiko
- Člen | 10
Měl bych ještě jeden poslední dotaz:
Celou aplikace jsem překopal do verze 2.O Beta. Použil jsem ve výsledku ten
samý kus kódu pro celý proces zisku elementů na stránce. Nyní mi laděnka
píše, že vykonává následující SQL dotaz dvakrát.
Oproti původnímu návrhu jsem jen trochu změnil strukturu tabulek v modelu,
abych mohl tahat elementy do různých prezenterů stejným modelem (změnou sql
v modelu). To by ale nemělo mít vliv.
SELECT `Typ`, `Nazev`, `Hodnota`, `Top`, `Left`, `V`, `S`
FROM (
select *
from `position` natural join `elements`) t
WHERE (`location`='index')