Zachovani vysledku z databaze pri opakovanem volani presenteru pro strankovani

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

Zdravim,

pokousim se vytvorit strankovani nad vysledky z databaze z vyhledavani. Co jsem koukal do nekolika vlaken, tak se vetsinou strankovani chova tak, ze pri zmene stranky znovu saha do databaze (jestli vse spravne chapu). V mem pripade bych ale byl rad, kdyby strankovani nemuselo znovu sahat do databaze, ale pouze prekreslilo view tak, aby zobrazoval spravna data ze stranky.

Nize mam vypsanou celou tridu SearchPresenter, ktera by toto vse mela obsluhovat. Myslenka je takova, ze odeslanim formulare, se mi z databaze nactou data do privatni promenne presenteru $resultSet. A volanim renderDefault vypisu pozadovana data.

Problem vsak nastava, pokud po odeslani formulare chci zmenit stranku a volam metodu renderDefault, tak je promenna $resultSet prazdna. Je mozne nejak zachovat data mezi jednotlivymi prekreslenimi? Nebo by bylo dobre pouzit uplne jiny pristup?

class SearchPresenter extends BasePresenter {

    private $database;
    private $searchModel;
    private $num = 0;
    private $resultSet = Array();
    private $resultsPerPage = 10;

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

    public function renderDefault($page = 1) {
	$this->renderResults($page);

    }

    protected function createComponentSearchForm() {
    }

    public function searchSent(UI\Form $form, $values) {
	$searchValue = $values->Search;

	if (substr($searchValue, 0, 1) == '"' && substr($searchValue, -1) == '"') {
	    $this->phraseSearch($searchValue);
	} else {
	    $this->basicSearch($searchValue);
	}
    }

    private function basicSearch($searchValue) {
	$searchValue = str_replace("*", "%", $searchValue);
	$searchValue = str_replace("!", "_", $searchValue);
	foreach (explode(" ", $searchValue) as $value) {
	    $results = $this->searchModel->searchKeywords($value);
	    if ($results !== false) {
		$this->resultSet = array_merge($this->resultSet, $results);
	    }
	}
	$this->renderResults();
    }

    private function phraseSearch($searchValue) {
	$phrase = str_replace('"', '', $searchValue);
	$result = $this->searchModel->searchPhrase($phrase);
	$this->resultSet = $result;
	$this->renderResults();
    }



    public function renderResults($page = 1) {
	$inputs = $this->resultSet;
	Debugger::dump($this->resultSet);
	if (!empty($inputs)) {
	    $resultsCount = count($inputs);
	    usort($inputs, array($this, 'cmpLinkObjectsByWeight'));

	    $pages = ceil($resultsCount / $this->resultsPerPage);
	    $this->template->pages = $pages;
	    $this->template->count = $resultsCount;
	    $this->template->inputs = array_slice($inputs, 0, 10);
	} else {

	}
    }

    private static function cmpLinkObjectsByWeight($a, $b) {
	return $b->getWeight() - $a->getWeight();
    }

}
CZechBoY
Člen | 3608
+
+1
-

Já bych si zacachoval výsledek hledání v tom modelu a pak bych do presenteru vrátil jen ořezaná data.

Muhahe
Člen | 79
+
0
-

Cachovat vysledek myslis nejak takto? To mi prijde trosku kostrbate, takze budto musim cachovat, nebo pokazde sahat pro data do database? Neni mozne jinym zpusobem uchovat data v presenteru/modelu?

CZechBoY napsal(a):

Já bych si zacachoval výsledek hledání v tom modelu a pak bych do presenteru vrátil jen ořezaná data.

CZechBoY
Člen | 3608
+
+1
-

@Muhahe nevim jak moc kostrbatý ti to přijde, ale mně se to zdá ok

presenter

$this->model->getData($searchTerm, $paginator->getLength(), $paginator->getOffset());

model

public function getData($searchTerm, $limit, $offset)
{
	$key = $searchTerm;

	$data = $this->cache->load($key);

	if ($data === null) {
		$data = $this->db->table('abc')->where('searchCol', $searchTerm)->fetchAssoc('[]->'); // tady můžeš zavolat třeba tu tvoji starou funkci na získání všech dat

		$this->cache->save($key, $data);
	}

	return array_slice($data, $offset, $limit);
}

Editoval CZechBoY (27. 7. 2016 14:02)

Muhahe
Člen | 79
+
0
-

Ano vypada to ze mas pravdu. Moc jsem si to neumel predstavit, jak by to vypadalo s invalidaci cache a jakou bych mel nastavit expiraci. Ale je fakt, ze asi vymejslim hlouposti.

Moje puvodni myslenka byla, ze bych sahal ciste na vygenerovanou promennou. Coz asi uplne odporuje tomu jak MVP funguje. Budu si muset jeste trochu procistit teorii. Jinak diky moc za inspiraci, zkusim to smontovat

CZechBoY napsal(a):

@Muhahe nevim jak moc kostrbatý ti to přijde, ale mně se to zdá ok

presenter

$this->model->getData($searchTerm, $paginator->getLength(), $paginator->getOffset());

model

public function getData($searchTerm, $limit, $offset)
{
	$key = $searchTerm;

	$data = $this->cache->load($key);

	if ($data === null) {
		$data = $this->db->table('abc')->where('searchCol', $searchTerm)->fetchAssoc('[]->'); // tady můžeš zavolat třeba tu tvoji starou funkci na získání všech dat

		$this->cache->save($key, $data);
	}

	return array_slice($data, $offset, $limit);
}