ExtJs cikkek =]
Sziasztok!
Nemrég kezdtem el foglalkozni extJs-el, és úgy döntöttem, hogy saját keretrendszer írása helyett jobb lesz ezt megtanulni kezelni. Weblaboron sajnos nincs kint egy cikk sem ezzel a keretrendszerrel kapcsolatban. Ha lenne közületek valaki, aki régóta ismeri a keretrendszert, és hajlandó lenne cikket írni róla, vagy akár csak egy részéről annak nagyon örülnék, és szerintem még sokan mások is rajtam kívül. :-)
Valószínűleg majd én is írok róla később, ha már jobban beletanultam, hogy hogyan mennek extJs-ben a dolgok. Ami elsőre tetszik, hogy az adat és a megjelenítés elég élesen elválik egymástól. Sajnos a leírás nem a legjobb hozzá, ill. arra sem találtam még cikkeket, hogy melyik objektum pontosan mire való. Most konkrétan egy layout szerkesztőn dolgozok, ami drag&drop-pal megy. Úgy gondoltam, hogy egy speckó TreeNodeUI-val meg tudom oldani a dolgot, hamarosan kiderül, hogy igazam volt e, vagy bebukom a projektet.
Nehéz volt gyorsan indulni extJs-el (péntek óta nézegetem). Van egy speciális adatformátumom, de nem tudom, hogy melyik objektumokat kell kiterjeszteni ahhoz, hogy ebbe a formátumba lehessen menteni egy fát, vagy ilyen formátumból kiolvasni. Végül az lett, hogy kiterjesztés helyett írtam saját osztályokat, amik TreeNode-okból felépítik a fát. Ha esetleg tudtok valami átfogó leírást arról, hogy melyik objektum nagyjából mire való, meg arról is, hogy a TreeNodeUI-t hogy érdemes kiterjeszteni, akkor azt nagyon megköszönném.
■ Nemrég kezdtem el foglalkozni extJs-el, és úgy döntöttem, hogy saját keretrendszer írása helyett jobb lesz ezt megtanulni kezelni. Weblaboron sajnos nincs kint egy cikk sem ezzel a keretrendszerrel kapcsolatban. Ha lenne közületek valaki, aki régóta ismeri a keretrendszert, és hajlandó lenne cikket írni róla, vagy akár csak egy részéről annak nagyon örülnék, és szerintem még sokan mások is rajtam kívül. :-)
Valószínűleg majd én is írok róla később, ha már jobban beletanultam, hogy hogyan mennek extJs-ben a dolgok. Ami elsőre tetszik, hogy az adat és a megjelenítés elég élesen elválik egymástól. Sajnos a leírás nem a legjobb hozzá, ill. arra sem találtam még cikkeket, hogy melyik objektum pontosan mire való. Most konkrétan egy layout szerkesztőn dolgozok, ami drag&drop-pal megy. Úgy gondoltam, hogy egy speckó TreeNodeUI-val meg tudom oldani a dolgot, hamarosan kiderül, hogy igazam volt e, vagy bebukom a projektet.
Nehéz volt gyorsan indulni extJs-el (péntek óta nézegetem). Van egy speciális adatformátumom, de nem tudom, hogy melyik objektumokat kell kiterjeszteni ahhoz, hogy ebbe a formátumba lehessen menteni egy fát, vagy ilyen formátumból kiolvasni. Végül az lett, hogy kiterjesztés helyett írtam saját osztályokat, amik TreeNode-okból felépítik a fát. Ha esetleg tudtok valami átfogó leírást arról, hogy melyik objektum nagyjából mire való, meg arról is, hogy a TreeNodeUI-t hogy érdemes kiterjeszteni, akkor azt nagyon megköszönném.
Jól döntöttél...
Ahm, köszi, ez a serializer
Vannak furcsaságai extjs-nek, pl én TreeNode-on beállítottam, hogy expandable: false, és mégis összecsukható... Meg csináltam egy Window-ot, amit ha X-el zárok be, és újranyitok, akkor a következő megjelenítés helyett a fámat kezdi el módosítani az extjs. Nem tudom ez mennyire normális, mindenesetre én kiszedtem az X-et, és raktam bele ok/cancel gombokat hide-al. Úgy már nincs gond.
Most olvasom a Learning extjs-t, hátha segít.
Ötletek
A TreeNodeUI-val a fa node-jainak kinézetét tudod befolyásolni. A layout szerkesztő feladatot még nem értem teljesen, ki tudnád fejteni (mit tud, hogy néz ki)?
A window-os kódrészletet ha bemásolod tudok segíteni. Furcsaságok akkor szoktak előjönni, ha az oldalon ID ütközés van. Pl az jutott most eszembe, hogy a window closeAction property-je hide-ra van állítva close helyett és ilyenkor csak elrejti az ablakot, ami nem baj, ha nem adsz meg az ablaknak id-t vagy nem hozod létre újra az ablakot. Mert két ablak ugyanolyan id-vel nem túl optimális. :)
A Learning extjs nagyon jó alapnap, biztos segíteni fog.
Nem adtam nekik id-t, szóval
A layout szerkesztő, amit csinálnom kell. Nagyjából úgy képzeld el, hogy az oldaladat feldarabolod oszlopokra, aztán ezekbe lehet további oszlopokat vagy tartalmakat (menü,kereső,hírek etc...) tenni. Nekem meg annyi a feladatom, hogy erre a egy drag-drop-os szerkesztőt csináljak. Na most ha belegondolsz, akkor ez a layout egy szimpla dom tree, tehát egy tree-vel meg lehet oldani a szerkesztését. A ki meg bepakolható elemeket meg egy (egyoszlopos) grid-ben vagy egy másik fában lehet tárolni, aztán onnan berántani a layout fába. Kb így képzeltem el. Az alap fa ui nyilván nem úgy néz ki, mint ahogy egy weblap, szóval módosítani kell a kinézetén. Egyelőre csak annyit akarok változtatni rajta, hogy kicsi dobozok legyenek egymásban, és mindegyiknek legyen egy neve. Meg a fának mindig nyitott állapotban kell lennie.
Köszi a fórum linket, megnézem hamarosan.
Learning extjs
szerk:
Na elolvastam a könyvet, végülis hasznos volt, de nem eléggé: uiProvider-ről egy szó nem esett... Nézegettem 1-2 fórumot, aztán szépen lassan összeállt a kép. Ha az ember JSON-ból tölti be a fát, akkor a TreeLoader hozza létre a node-okat, és ő állítja be az uiProvider-t a createNode metódusában. A TreeLoader-nek több provider-t meg lehet adni amiket egy map-ben tárol. Azt, hogy melyik node milyen providert kap a JSON-ban kell megadni.
json:
fail :S
Kicsit szőrszálhasogatás, de ha már quicktips init meg sima init, meg ki tudja még hányféle init lehet, akkor én csinálnék egy init osztályt, aminek a példányába be lehet regisztrálni, hogy mit akarunk inicializálni, és ami automatikusan beteszi magát az onReady-be...
Találtam egy egész értelmes összefoglalót extjs-ről, valami ilyesmi kellett volna, amikor indítottam ezt a topicot: link.
szerk:
A TreeNode és TreeNodeUI rész ott van elhibázva, hogy nem elég laza a csatolás közöttük. A TreeNode direktbe hívja meg a TreeNodeUI metódusait, ezért bonyolult új ui-t írni hozzá. A jobb megoldás az lenne, ha a TreeNode-nak lennének a megjelenítésre vonatkozó eseményei, melyeknek a kezelésére az ui beregisztrálna eseménykezelőket a létrejöttekor, ill. kiszedné ezeket a kezelőket a törlésekor/leválasztásakor. Így további előny lenne, hogy ugyanazt a node-ot egyszerre több ui-val is meg lehetne jelenítetni.
Egy másik dolog, hogy a TreeNodeUI-ban sima HTML-ből készülnek a dolgok. Ez nem feltétlen gond, viszont én jobb szeretném a TreeNodeUI-t valamilyen Panel-ből kiterjeszteni, hogy egyszerűbben fejleszthető legyen. A TreeLoader-rel kapcsolatban is vannak dolgok, amik nem tetszenek, szóval végső soron az lesz, hogy mindent átírok.
Biztos TreePanel?
Ennél komolyabb változás esetén szerintem már felmerülhet, hogy nekünk nem is biztos, hogy a TreePanel-re van szükségünk. Szerintem, ha pusztán panel elemeket drag&drop –pal szeretnénk egymásba helyezni, akkor a TreePanel ágyúval verébre.
Egyelőre így állok
Lehet tesztelni, meg kiegészíteni... Drag-drop, meg hasonló nyalánkságok még nincsenek benne, csak a megjelenítés, meg append, insert, remove van beleépítve.
Ezek a kiterjesztések olyan dolgok, hogy csinálja meg mindenki magának, én adtam egy jó alapot extjs-ben a fák kezelésére, viszont nincs kedvem mások helyett dolgozni. :-)
A drag-drop-ot még ki fogom dolgozni hamarosan, mert kell egy projecthez. Azt még talán megosztom, nem tudom mennyire zűrös extjs-ben.
Néhány apróság.
A Ext.ux.tree.TreePanel tartozik a Ext.ux.tree.Tree-hez, vagy fordítva? Számomra zavaró, hogy milyen könnyedén hívogatják egymás belső függvényeit, szerintem kellene egy kis ide-oda pakolás, hogy csak az egyik irányba történjen a hívás.
Megnéztem az Ext kódját, de a save eseményt alig látni, miért nem change? :)
TreePanel konstuktorában mi történne, ha a load render előtt futna le? miért kell az a vizsgálat, illetve előfordulhat-e, hogy render előtt fut le?
Nem akarnál egy jobb példát csinálni? Mert az eszköz valószínűleg sokkal erősebb, mint, amit a példakód mutat.
(zárójelben, Weblaborból forráskódot ki lehet úgy másolni, hogy a sorszámot ne másoljon... elég zavaró:)
Szia! A save még alakulni
A save még alakulni fog, nem néztem meg, hogy hogyan működik egy sima serializer, majd ahhoz igazítom.
Az Ext.tree-nél is úgy van, hogy a TreePanel-hez tartozik minden, itt annyi a különbség, hogy a TreePanel létrehozza az adatokat tároló Tree-t, szóval a kettő mindig együtt jár, ezért nincs értelme különrakosgatni a dolgokat, de azért kíváncsi vagyok szerinted mi van rossz helyen?
Huhh, a renderrel megfogtál :-) Ránézésre nem lenne hatása, ha render előtt tolnám a loadot, szóval az ellenőrzést nyugodtan ki lehet venni. (Talán a drag&drop hozzáadásánál szükséges, hogy renderelve legyenek az elemek, amikor dropTarget-et meg dragSource-ot adok a rendszerhez. Majd megnézem...)
Köszi a hozzászólásokat, tényleg hasznosak voltak. Izmosabb példát majd később tolok, mert most átalakítás alatt van a kód, meg próbálom beletákolni a csoportok kezelését meg a drag&drop-ot. Alapból gondoltam olyanra a csoportokkal kapcsolatban, hogy a node-kat automatikusan több szintes csoportokba teszi a megjelenítésnél valami alapján. Valszeg ilyen lesz majd a példa, de az még 1-2 hét, mert kevés az időm mostanában ilyesmire. A drag-drop meg elég nehéz dió, pl nem tudom, hogy hogy lehet elérni, hogy jelezze, ha két panel közé ejtek be valamit, valszeg az lesz, hogyha a title-ra ejti, akkor számít majd két panel közöttinek, ha meg a body-ra, akkor meg magába a panel-be rakom majd. Egyelőre nincs jobb ötletem...
A forráskódra rá kell ereszteni egy "\s+\d+\.\s+" => "" replace-t, aztán jó lesz. :-) Amúgy tényleg zavaró, elvileg valahogyan csatolni is lehet forráskódot, de még nem jöttem rá, hogy hogyan. Inkább kiteszem majd githubra valamikor.
(A move része, amit kikommenteztem nem fog kelleni, mert remove+append/insert-ből áll össze.)
Ide-oda pakolás
Nekem elsőre a 11. sorban lévő esemény elkapását jelentette problémát, elsőre szerintem arra gondolna az ember, hogy azért csinálsz ilyet, hogy a két osztályt különválaszd, legalábbis eseménykezelést sok esetben ezért csinálunk. De itt az eseményhez nem rendelsz scope-t, így az a függvény egy az egybe átmehetne a Tree-hez. (Magyarul: létrehozol egy fát, majd létrehozás után azt mondod egy másik osztályba, hogy bizonyos esetekben csináljon valamit. Na, de ezt miért a TreePanel –nek kell mondani, vagy legyen ez initConfig, de akkor se esemény után)
A másik, hogy az uiProvider kihez tartozik? Az eredeti példádban még a node-khoz, jelenleg a TreePanel-hez. Ez sem biztos, hogy jó, az uiProvider helye a node, ha ott nincs, akkor mehetünk megkeresni. :)
Végül a root létrehozása sem biztos, hogy a helyén van, a TreePanel load-ja megkéri a fát, hogy hozzon létre egy node-t, majd ha ez sikerült, akkor a fánál beállítjuk, hogy ez a node legyen a gyökér elem. Nem lenne egyszerűbb a config-ot átadni a fának? (például elsőre létrehozáskor)
Mindamellett én itt az ellenőrzést lecserélném. 1. hiba dobásával leállnék. nincs fa gyökérelem nélkül. 2. valami root elemet azért is csinálnék, még ha elsőre nem is sikerült. :)
Illetve a kódot véleményem szerint kicsit összébb kellene nyomni. (és most nem a formázásra gondolok), több esetben olyan feltétel vizsgálat van, aminek semmi haszna. doLayout meghívható rendered nélkül is. Ezek a lényegről elviszik a figyelmet.
Félre ne értsd, ha nem tetszene az ötlet, akkor nem foglalkoznék ezzel a kóddal ennyit! :-) Illetve még egyszer megjegyzem, hogy az itt leírtakat nem próbáltam ki, csupán ötletelés, gyakorlat lehet, hogy az ellenkezőjét igazolná. :)
Yepp, még van mit tákolni
Az onrootnodeset is emiatt van, ha beállítom a rootnode-t, akkor a megjelenítésnél is hozzá kell illesztenem a TreePanel-hez.
A createNode-hoz létrehozok egy "nodecreate" eseményt majd, és a TreePanel ahhoz fog beregisztrálni, hogy létrehozza a node-hoz az UI-t, így a Tree a megjelenítéstől függetlenül is létezhet... A getUI meg setUI metódusokkal még lehet, hogy lesz valami, ami a különválasztást szolgálja majd, a lényeg, hogy a végére olyan lesz, hogy több panel tud majd felcsatlakozni ugyanarra a fára, és megjeleníteni vagy manipulálni az adatokat. Valszeg hasonlóan lesz, mint a grid és store esetében, külön kell majd létrehozni a fát, ami az adattárolást csinálja, és külön kell a Paneleket, szóval a fa létrehozása ki fog kerülni a TreePanel konstruktorából, ahogy a Loader és a Serializer is, mert ugye az adatot töltöd be meg szerializálod, nem a megjelenítést. :-) Tényleg van még mit áthelyezni rajta, de lassan kialakul. :-)
Az uiProvider az a defaultUIProvider és a megjelenítéshez tartozik. Ebben a verzióban még nincs benne, hogy uiProviders map-et hozunk létre a treePanel-en, és oda tesszük azonosítóval az osztályokat, majd a node-ban azonosítóval hivatkozunk rájuk. Persze még ennél is tovább lehet menni, leginkább olyan irányba, hogy csinálunk egy detectProvider metódust az TreePanel-en, ami megállapítja a node valamilyen adata alapján, hogy milyen provider tartozik hozzá. Ez persze lehet ugyanúgy az uiProvider attribútum, de akár az is, hogy "A" betűvel kezdődik a szöveg rajta, vagy hogy levél vagy ág e, vagy bármi más.
A refresh új nevet kapott: onChange. Még várható valami olyasmi is, hogy egy bizonyos node-hoz tarozó UI dinamikusan lecserélhető lesz, vagy akár az egész fához tartozó uiProviders map is lecserélhető lesz, és a fa újraépíti magát az új map alapján... Ez a része még olyan, hogy sokféleképp meg lehet oldani, aztán most gondolkodok rajta, hogy mi a célszerű...
Van még olyan dolog is, hogy a loader-nek onLoad eseménnyel kell értesítenie a Tree-t majd, hogy megjöttek az adatok, és lehet kirajzolni a root-ot, mert a mostani megoldás csak szinkron módra alkalmazható.
A doLayout-nál volt egy ciklus, ami végigment az összes szülő elemen, ez nekem kellett egy saját megjelenítéshez, aztán átírtam a saját megjelenítőt, és kiszedtem a ciklust, a rendered meg bent maradt véletlenül. Ártani végülis nem árt :-)
Majd még ebben a hónapban frissítem a cuccot, az a helyzet, hogy van két szigorlatom, aztán 2 hétig biztos nem lesz időm ilyen fejlesztésekkel foglalkozni, csak annyival, ami a projekthez kell, mert már le kellett volna adnom a kódot. Valamikor január vége fele kiteszem github-ra, meg írok ide is.
szerk:
Ezt még lehet nem válaszoltam meg eléggé:
Azért eseményekkel oldom meg majd teljesen a Tree és a TreePanel közötti kommunikációt, mert akkor a TreePanel bármikor leválasztható lesz a Tree-ről, vagy visszailleszthető rá. Szóval a TreePanel-nél jó helyen van, az eseménykezelőhöz reggelés, annyi, hogy a setTree-be kéne áttenni majd, meg ha előzőleg már lett fa beállítva, akkor arról le kell választani a TreePanel-t. A TreePanel és a Tree kommunikációját teljesen átírom ilyen eseménykezelősre majd, a node.setUI,getUI helyett meg megpróbálom máshogy lekérdezni, hogy melyik UI tartozik egy node-hoz. Elvileg minden tree elem kap egy id-t, szóval valszeg {node.id => ui} map lesz, az ui-nál meg marad a setNode,getNode, mert az csak egy node-hoz tartozhat, egy node viszont több ui-hez is. Remélem így már érthető, ha nem, akkor kérdezz nyugodtan.
Közben átgondoltam ezt az
Másolás
Kijelölés != Másolás
Megnéztem az Ext kódját, de a
Közben megnéztem én is, az Ext.data.Store load illetve save metódusokkal tölti be, és menti az adatokat, a Loader és a Serializer is ugyanezeket a funkciókat fogja ellátni a tree-nél, szóval szerintem maradhat a save elnevezés.
Ha lesz időm/energiám
Biztosan van.
Engem érdekelne
:)))
De akár egy step by step is!
:)))
Köszi, ha megcsinálod!
:)
aet
extjs.blog.hu
Yii
Közben elkészültem a fa
Ext.ux.tree
Van egy egyszerű példa, többre sajnos most nem volt időm. Néhány dolog még nincs letesztelve benne, ha valaki hibát talál, vagy egyéb észrevétele van, akkor legyen szíves szóljon itt, vagy küldjön mailt.
szerk:
Közben javítottam benne egy kisebb hibát, meg betettem a példába az adathoz még egy megjelenítőt, csak, hogy érzékeltessem mire képes a rendszer.
szerk2:
Töröltem belőle a builder patternt, mert feleslegesen bonyolította csak. Raktam bele proxy,reader,writer osztályokat, hogy lehessen szervertől leszedni és szerverre feltölteni a fát. Az egész nagyjából hasonló felületű lett, mint az Ext.tree-ben megadottak azzal a különbséggel, hogy ott a node.ui-val lehetett elérni a dolgokat, itt meg az ui.node-al, és a tree/node eseménykezelői hívják meg az ui objektumok metódusait. Így elég lazán csatolt lett a cucc, annyira, hogy több view-t is be lehet állítani ugyanahhoz a modelhez. Az adatok betöltéséért és mentéséért a TreeStore a felelős, bármilyen adat formát lehet használni megfelelő reader és writer beiktatásával, alapból a JSONReader és JSONWriter van megírva. A lényeg, hogy a tree-nek olyan objektum kell, mint amit az Ext.tree-ben json-ban adunk meg. A proxy alapból úgy van beállítva, hogy a megadott url-ről gettel szedje az adatokat, és posttal küldje vissza őket mentésre. Persze egy kis átírással szinte bármit el lehet érni. Körülbelül ennyi, amit tud, most írok egy komolyabb projektet erre építve, drag-droppal, csoportosítással meg mindennel, ha készen lesz, akkor kiteszem azt is. Ez valszeg a héten még megtörténik.