Salut à tous
je travail depuis maintenat quelques temps avec ExtJS
j'ai rencontré quelqes petits pbs et j'ai trouvé quelques bricoles pour lever certaines limitations
Les tableaux javascripts
Propriétées:
- length
Méthodes :
- concat()
- join()
- pop()
- push()
- reverse()
- shift()
- slice()
- splice()
- sort()
- unshift()
Metodes ajoutées par Extjs
- indexOf()
- remove()
si vous utilisez les tableaux comme des piles (FILO) vous pouvez utiliser push et pop pour ajouter et suprimer des éléments dans votre pile.
Mais vous n'avez rien pour lire sans l'enlever l'élément qui est au sommet de la pile. vous pouvez soit faire un pop push soit calculer l'index du sommet pour lire l'élément. ce simple code ajoute la methode top pour lire cet élément
Vous avez alors toutes les méthode necessaire au fonctionnement d'une pile
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 /** * @class Array */ Ext.applyIf(Array.prototype, { /** * Return the last object in array * @return {Object}|null The objec in the array (or null if it is not found) */ top : function(){ if (0 == this.length){ return null; } return this[this.length -1]; } });
- pop()
- push()
- top()
Les classes extj
Extjs utilise des classes qui embarquent des informations sur elles-même dans les objets crées. il est parfois intéréssant de pouvoir connaitre les classes utilisées par un objet.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 Ext.applyIf(Object.prototype, { getClass : function(){ if (this.constructor&&this.constructor.prototype&&this.constructor.prototype.baseCls) { return this.constructor.prototype.baseCls; } else { return undefined; } }, getSuperClass : function(){ if (this.constructor&&this.constructor.superclass&&this.constructor.superclass.baseCls) { return this.constructor.superclass.baseCls; } else { return undefined; } }, isInstanceOf :function(aClass){ return (aClass == this.getClass()); }, isA: function(aClass){ if (undefined == this.getClass()) { return false; }else if (this.isInstanceOf(aClass)) { return true; } else { return this.constructor.superclass.isA(aClass); } } });L'objet Ajax
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 this.getClass(); //=> x-window this.getSuperClass(); //=> x-panel this.isInstanceOf('x-window'); //=> true this.isInstanceOf('x-panel'); //=> false this.isA('x-window'); //=> true this.isA('x-panel'); //=> true
l'objet Ajax peut être utilisé plusieurs fois mais on est par fois surpris pas son comportement c'est simplement qu'apres usage l'objet ajax garde les handler déjà définis. cela est parfois pratique mais généralement mieux vait nettoyer tout ça
Les cookies
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // When ajax request are complete remove all handler. Ext.Ajax.on('requestcomplete', function(ajax, xhr, o){ if(typeof urchinTracker == 'function' && o && o.url){ urchinTracker(o.url); } });
Lorsque on place un cookie c'est généralement dans le domaine dans lequel on se trouve. il fat donc regarder l'url de la page et calculer ce domaine. mais attention car un cookie ne peux être placé dans un domaine sans '.'
ce petit code ajoute la methode getDefaultDomain au CookieProvider d'Extjs pour récupérer le domaine par defaut.
Les tabPanels
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Ext.state.CookieProvider.getDefaultDomain = function () { var mots = location.hostname.split("."); var domain = ""; for(var i = 1; i < mots.length; i++) { domain = domain + "." + mots[i]; } return ("" == domain) ? null : domain; }
Les tabPanels sont bien pratique en autre il est agréable de pouvoir les imbriquer les uns dans les autres lorsqu'on travaille sur beaucoup d'éléments imbriques. ils offre alors la particularité de pouvoir mettre les onglets en bas. Mais là hélas les tabPanel ne savent plus gérer les ascensseurs de façon automatique. c'est du à quelques lignes d'Extjs qui ne tiennent pas compte de la position. heureusement Extjs peut facilement être patché dynamiquement.
templates et Panel
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 //patch tab panel for autoscroll at bottom Ext.TabPanel.prototype.autoScrollTabs= function(){ var count = this.items.length; var ce = this.tabPosition != 'bottom' ? 'header' : 'footer'; var ow = this[ce].dom.offsetWidth; var tw = this[ce].dom.clientWidth; var wrap = this.stripWrap; var wd = wrap.dom; var cw = wd.offsetWidth; var pos = this.getScrollPos(); var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos; if(!this.enableTabScroll || count < 1 || cw < 20){ return; } if(l <= tw){ wd.scrollLeft = 0; wrap.setWidth(tw); if(this.scrolling){ this.scrolling = false; this[ce].removeClass('x-tab-scrolling'); this.scrollLeft.hide(); this.scrollRight.hide(); if(Ext.isAir){ wd.style.marginLeft = ''; wd.style.marginRight = ''; } } }else{ if(!this.scrolling){ this[ce].addClass('x-tab-scrolling'); if(Ext.isAir){ wd.style.marginLeft = '18px'; wd.style.marginRight = '18px'; } } tw -= wrap.getMargins('lr'); wrap.setWidth(tw > 20 ? tw : 20); if(!this.scrolling){ if(!this.scrollLeft){ this.createScrollers(); }else{ this.scrollLeft.show(); this.scrollRight.show(); } } this.scrolling = true; if(pos > (l-tw)){ wd.scrollLeft = l-tw; }else{ this.scrollToTab(this.activeTab, false); } this.updateScrollButtons(); } }; Ext.TabPanel.prototype.createScrollers = function(){ var ce = this.tabPosition != 'bottom' ? 'header' : 'footer'; var h = this.stripWrap.dom.offsetHeight; var sl = this[ce].insertFirst({ cls:'x-tab-scroller-left' }); sl.setHeight(h); sl.addClassOnOver('x-tab-scroller-left-over'); this.leftRepeater = new Ext.util.ClickRepeater(sl, { interval : this.scrollRepeatInterval, handler: this.onScrollLeft, scope: this }); this.scrollLeft = sl; var sr = this[ce].insertFirst({ cls:'x-tab-scroller-right' }); sr.setHeight(h); sr.addClassOnOver('x-tab-scroller-right-over'); this.rightRepeater = new Ext.util.ClickRepeater(sr, { interval : this.scrollRepeatInterval, handler: this.onScrollRight, scope: this }); this.scrollRight = sr; };
Les template permettent de définir des modèles d'affichage et les panel des conteneurs. Or chose étrange Extjs n'offre pas de les associers.
voici un code trouvé sur le forum d'Extjs.com qui ajoute ce manque.
il es d'usage de placer les extention à ext dans le namespace Ext.ux (user extensions)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 //add templatePanel class Ext.namespace('Ext.ux'); Ext.ux.TemplatePanel = Ext.extend(Ext.Panel, { initComponent: function() { Ext.ux.TemplatePanel.superclass.initComponent.call(this); if (typeof this.tpl === 'string') { this.tpl = new Ext.XTemplate(this.tpl); } }, onRender: function(ct, position) { Ext.ux.TemplatePanel.superclass.onRender.call(this, ct, position); if (this.data) { this.update(this.data); } }, update: function(data) { this.tpl.overwrite(this.body, data); } }); Ext.reg('templatepanel', Ext.ux.TemplatePanel);
Panel et layout
les layout permettent de definir des positionnement d'élément dans un contener. dans les exemple sur les Panel on trouve l'attribut 'layout: "table"' afec la description du contenus ensuite. cela ne fonctionne pas toujours. et il faut redimentionner le contener pour voir apparaitre le contenus. il se trouve que l'objet Panel vas transformer la shiane "table" de l'attribut 'layout' en objet sur certains évènements. mais pas lors de l'affichage initial. voici un pout de code à ajouter dans la construction de votre panel pour résoudre ce problème.
Chargement asynchrone
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 onRender: function(ct, position) { Ext.ux.TemplatePanel.superclass.onRender.call(this, ct, position); if (this.layout) { if(typeof this.layout == 'string'){ this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig); } this.setLayout(this.layout); this.doLayout(); } },
lorsqu'on a beaucoup de scripts à charger il es efficace de le faire de façon asynchrone. on lance des appel ajax les un après les autres et les scripts se chargent. lorsque chacun d'eux à fini il exécute sa méthode success ou failure associé. mais comment savoir que tous ont fini ? (cela est vrais pour tous les traitement assynchrone) comment fixer un point de rendez-vous à un ensemble d'appel assynchrones ?
la solution consiste à monitorer les fins de traitements. au début on place la liste des traitements à éffecturer dans un coin puis on lance tous ces traitements. chque fois que l'un deux à fini on le retire de la liste lorsque le dernier sort tous les traitements sont arrivés à leur terme.
cette classe definit des objets de syncronisation;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 //sync tread Ext.app.SyncTread = function(cfg){ Ext.apply(this, cfg); this.items = []; this.addEvents({ 'ready' : true }); }; Ext.extend(Ext.app.SyncTread, Ext.util.Observable, { isReady : false, add: function(item) { //system.trace(this.name + ' add '+item); this.items.push(item); }, afterLoad: Ext.emptyFn, after: function(item) { //system.trace(' <b>after</b> ' + this.name + ' '+item); try{ this.items.remove(item); } catch(e){} if(0 === this.items.length) { this._afterLoad(); } }, _afterLoad: function() { this.fireEvent('ready', this); this.isReady = true; if (this.afterLoad) { //try { this.afterLoad(); //}catch(e){} } }, onReady: function(fn, scope){ if(!this.isReady){ this.on('ready', fn, scope); }else{ fn.call(scope, this); } } });
voilà je crois que c'est à peut près tout pour aujourd'hui
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 var lodingSync = new Ext.app.SyncTread({ name: 'loding', afterLoad: function() { alert('All modules Loaded'); } }); lodingSync.add('Login'); // ajout d'un éléments à synchroniser //ajout d'un traitement à faire apres la synchronisation lodingSync.onReady( function() { new Ext.app.Login(system.config.module.Login); } ) // lancement du traitement Assynchrone ... lodingSync.after('Login'); // retrait de l'élément (ce code est à placer dans la methode success d'un appel ajax par exemple)
A+JYT
Partager