Grido – vlastní sloupce, řazení, filtrování
- kolsi
- Člen | 131
Ahoj,
už jsem tenhle problém řešil asi tisíckrát, ale ještě nenašel žádné rozumné řešení. Teď už to ale začíná být kritické.
Jednoduše – mám Grido, v něm zobrazuji data z NDB. Některé sloupce však obsahují složenou hodnotu (např. jméno a příjmení uživatele ze sloupce „user_id“, nebo dobu trvání spočtenou ze sloupců „start“ a „end“ apod.). Následně chci podle všech sloupců řadit, filtrovat atd. Jak to elegantně vyřešit?
Řešení pomocí setColumn nebo setCustomRender je nepoužitelné. Sice tím vyřeším, že se vypíše ve sloupci to, co potřebuji, ale řazení/filtrování stejně nefunguje.
Do teď jsme používali nejrychlejší řešení – překlopit celý model do pole a použít jako ArraySource. To funguje dobře až na jednu drobnost – generuje se to pro všechna data, tj. i ta, která vůbec nebudou viditelná. Výsledkem je, že seznam, který obsahuje např. 9000 záznamů vyčerpá veškerou paměť, trvá to dlouho, stránka se vůbec nezobrazí atd.
Napadlo mě řešení univerzálního modelu, který jako zdroj použije NDB a teprve při pokusu řadit/filtrovat podle vlastního sloupce, překlopí do pole pouze tento sloupec a s ním pracuje. Ale nevím, jak moc by to skutečně fungovalo a co všechno bych v tom modelu musel vyřešit.
Má s tím něco zkušenost? Nějaké elegantní řešení?
Předem díky.
- kolsi
- Člen | 131
jj, pohledy bylo první co mě napadlo. Problém ale byl, že dost sloupců používá nějaký výpočet na pozadí, který nelze lehce převést do DB. Nakonec jsem to vyřešil tím vlastním modelem – používá Selection dokud to jde; pokud je požadavek (řazení/filtrování) na vlastní sloupec, tak udělá fetchAll() a pracuje s polem.
- raketoplan2005
- Člen | 147
@kolsi:
A pracuje s polem pouze s jedním sloupcem?
Mám stejný problém s dibi a grido – mám v tabulce 50 tisíc záznamů, groupovaných podle identifikátoru a do jednoho ze skloupců počítám sumu.
V Gridu pak ale už nedokážu dát filtr kde suma > x.
V jiných případech se pak při řazení v ArraySource potýkám s problémy s diakritikou.
Editoval raketoplan2005 (19. 5. 2015 17:48)
- kolsi
- Člen | 131
No, pokud zjistí, že pracuje s vlastním sloupcem, tak udělá fetchAll(), takže se do pole překlopí všechny záznamy, ale doplní se do nich jenom ty vlastní sloupce, se kterými se pracuje. Ostatní se doplní až v metodě getData (tzn. před tím než Grido bude vykreslovat). Navíc ještě používám vlastní ActiveRowRW (obdoba z Nette 2.0), které mi umožní ty vlastní sloupce doplnit rovnou do ActiveRow a nemusím ještě každý řádek zvlášť převádět do pole.
Nevýhoda je ta, že paměť vyžaduje pořád (tzn. musím zvýšit memory_limit v .htaccess na 256M). Hlavní výhoda je v čase zpracování.
- nechci řadit/filtrovat podle vlastního sloupce, tak nepotřebuje hodně paměti a vykreslení je okamžitě
- chci řadit/filtrovat podle vlastního sloupce, vyžaduje hodně paměti, zpracování je tak do 10 sekund (pro 9400 záznamů).
Původní stav byl:
- vždy vyžaduje hodně paměti a čas zpracování kolem 50 sekund.
Možná by to šlo udělat ještě líp, ale zatím nevím jak.
Problém řazení s diakritikou je způsoben tím, že ArraySource používá ksort/krsort, který řetězce porovnává podle ASCII jednotlivých znaků. U tohoto nového modelu používám uasort a v případě stringů použiju k porovnání strcoll.
- Pavel Kravčík
- Člen | 1195
Mám stejný problém. Bohužel kombinace YetORM a Grido asi nijak vyřešit nejde, kromě ArraySource.
Ještě se dají dělat falešné sloupce v DB podle, kterých se často hledá – například takhle:
Tabulka smlouva
- id = 1
- klient_id = 23
- klient_string = ‚Pavel Novák‘
Tím se dá obejít to mergovaní v array, ale je potřeba při uložení klienta uložit změnu i do tabulky smlouva.
@raketoplan2005: https://forum.nette.org/…id-pro-nette?p=15, já to vyřešil ošklivě přes pattern v rozšíření ArraySource.
Editoval kzk_cz (20. 5. 2015 10:28)