Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

ExtJS - rejuzabiliti

[es] :: Javascript i AJAX :: ExtJS - rejuzabiliti

[ Pregleda: 1453 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-1.sezampro.yu.



+33 Profil

icon ExtJS - rejuzabiliti04.07.2009. u 12:01 - pre 180 meseci
Evo uzeh juče, prekjuče malo da proučavam taj ExtJS, jer planiram da ga koristim u admin panelu jednog projekta. Uglavnom će se sve svoditi na korišćenje njegove Grid komponente...

Već sam napravio jedan grid, za pregled komentara, i on izgleda ovako:

Pri kreiranju sam koristio onaj Module Pattern.

E sad, problem je što će i ostali grid-ovi biti jako slični ovom. Naravno, razlikovaće se samo column modeli, data record-i, i sl. Takođe, neki će imati taj Paging toolbar, a neki ne. Ali ja sad ne znam kako da idem dalje, odnosno, kako je najbolje da odradim ove ostale grid-ove, a da pritom pazim na rejuzabiliti... Ok, znam da mogu da idem jednostavno copy-paste koda od ovog grid-a, pa da napravim odogovarajuće izmene, al' to mi je najgluplje rešenje.

Jako mi je konfuzno to OOP u JS-u... :S Ne znam uopšte u kom pravcu da krenem. Verovatno bih trebao da radim neko izvođenje, samo ne znam iz koje komponente, kako, šta...

Evo koda od ovog grid-a sa slike, ako vam išta znači:
Code:

Ext.namespace('WFAdminManage');

WFAdminManage.comments = function() {
    
    /******************/
    /*--Private Area--*/
    
    /*--Private Variables--*/
    
    var dataRecord; //Ext data record.
    
    var dataReader; //Ext data reader.
    
    var dataStore; //Ext data store.
    
    var colModel; //Column model.
     
    var grid; //Grid object.

    function setupDataSource() {

        dataRecord = Ext.data.Record.create([ 
            {name: 'id', type: 'int', mapping: 'id'},
            {name: 'WFItemTitle', type: 'string', mapping: 'title'},
            {name: 'authorName', type: 'string', mapping: 'author_name'},
            {name: 'authorEmail', type: 'string', mapping: 'author_email'},
            {name: 'authorUrl', type: 'string', mapping: 'author_url'},
            {name: 'authorIp', type: 'string', mapping: 'author_ip'},
            {name: 'text', type: 'string', mapping: 'text'},
            {name: 'datetime', type: 'date', mapping: 'datetime'},
            {name: 'status', type: 'string', mapping: 'status'}
        ]);

        dataReader = new Ext.data.JsonReader({
            root: 'results',
            totalProperty: 'total',
            id: 'id'
            },
            dataRecord
        );

        dataStore = new Ext.data.Store({
            id: 'dataStore',
            proxy: new Ext.data.HttpProxy({
                url: $('#base_url').val() + '/front-end/admin_show_grids_handler.php',  
                method: 'POST'
            }),
            baseParams:{action: 'comments', cond: 'not_spam'}, 
            reader: dataReader
        });     

        dataStore.load({params:{start:0, limit:20}});

    } 
    
    function getColumnModel() {
        if (!colModel) { //Only need to create columnModel if it doesn't already exist.

            function renderAuthorInfo(value, p, record) {
                var newNotify = '';
                if (record.data.status == 'awaiting') {
                    newNotify = '<b>new!</b>';
                }
        
                if (record.data.authorUrl.length > 0) {
                    return String.format('<span style = "font-size: 14px; font-weight: bold;">
                                    <a href="' + $('#base_url').val() + '/admin/manage/comment/{1}">{0}</a>
                                </span> ' + newNotify + '<br /> ({2} | {3} | {4})',
                        value, record.data.id, record.data.authorUrl, record.data.authorEmail, record.data.authorIp);
                }
                else {
                    return String.format('<span style = "font-size: 14px; font-weight: bold;">
                           <a href="' + $('#base_url').val() + '/admin/manage/comment/{1}">{0}</a>
                          </span> ' + newNotify + '<br /> ({2} | {3})',
                        value, record.data.id, record.data.authorEmail, record.data.authorIp);
                }
        
            }
    
            function renderDate(value, p, record) {
                return String.format(value.dateFormat('d/m/Y'));
            }
    
            function renderActions(value, p, record) {
                var status = '<a href="javascript: setStatus(\'ready\', ' + record.data.id + ');">Unapprove</a>';
                if (record.data.status != 'approved') {
                    status = '<a href="javascript: setStatus(\'approved\', ' + record.data.id + ');">Approve</a>';
                }
                return String.format(status + ' | 
                             <a href="javascript: markAsSpam(' + record.data.id + ');">Mark as spam</a> | 
                            <a href="javascript: deleteComment(' + record.data.id + ');">Delete</a>'
                        );
            }

            this.sm = new Ext.grid.CheckboxSelectionModel();
            
            colModel = new Ext.grid.ColumnModel([
                sm,
                {
                    header: 'Comment',
                    width: 430,
                    dataIndex: 'authorName',
                    renderer: renderAuthorInfo
                },
                {
                    header: 'Date',
                    width: 100,
                    dataIndex: 'datetime',
                    renderer: renderDate,
                    sortable: true
                },
                {
                    header: 'Actions',
                    width: 200,
                    dataIndex: 'id',
                    renderer: renderActions
                }
            ]);

        }
        
        return colModel;
    }
    
    function buildGrid() {   
    
        function refreshGrid() {
            dataStore.reload();
        }; 

         var pagingBar = new Ext.PagingToolbar({
            pageSize: 20,
            store: dataStore,
            displayInfo: true,
            displayMsg: 'Displaying comments {0} - {1} of {2}',
            emptyMsg: 'There is no any comment in your webfolio.'
        });
    
        grid = new Ext.grid.GridPanel({
            el:'comments_grid',
            width:730,
            height:560,
            store:dataStore,     
            cm:getColumnModel(),    
            disableSelection:true,
            sm:this.sm,
        
            viewConfig: {
                forceFit:true,
                enableRowBody:true,
                showPreview:true,
                getRowClass : function(record, rowIndex, p, store){
                    if (this.showPreview) {
                        p.body = '<div style = "margin-left: 3px;"> 
                                   <p>' + record.data.text + '</p> 
                                   <p style = " padding-top: 2px; border-top: 1px dashed;">
                                         In ' + record.data.WFItemTitle + ', ' + record.data.datetime.dateFormat('d/m/Y, H:i') + '
                                   </p> 
                                  </div>';
                        return 'x-grid3-row-expanded';
                    }
                    return 'x-grid3-row-collapsed';
                }
            },
        
            tbar:[
                {
                    text:'Approve',
                    tooltip:'Approve selected comments.',
                    handler: ''
                }, 
                '-', 
                {
                    text:'Unapprove',
                    tooltip:'Unapprove selected comments.',
                    handler: ''
                }, 
                '-', 
                {
                    text:'Mark as spam',
                    tooltip:'Mark selected comments as spam.', 
                    handler: ''
                }, 
                '-', 
                {
                    text:'Delete',
                    tooltip:'Delete selected comments.',
                    handler: ''
                },
                '-', 
                {
                    pressed:true,
                    enableToggle:true,
                    text:'Details',
                    tooltip:'Show/hide text of a comment.',
                    cls:'x-btn-text-icon details',
                    toggleHandler: function(btn, pressed){
                        var view = grid.getView();
                        view.showPreview = pressed;
                        view.refresh();
                    }
                }
            ],
        
            bbar: pagingBar
        });
     
        grid.render();
    }
    
    /*--Private Area--*/
    /******************/
 
    /*****************/
    /*--Public Area--*/
    return { 
        init : function() { 
            this.getGrid(); 
        },
       
        getGrid: function() {  
            Ext.QuickTips.init(); //Enables Quicktips.
            setupDataSource();
            buildGrid();
        },
    }
    /*--Public Area--*/
    /*****************/
}();

Kol'ko sam shvatio, ovo što sam ja uradio je neki singleton, a ne znam šta bih trebao da uradim pa da od svega ovoga napravim neku osnovu, koju će moći da koriste ostali grid-ovi.
 
Odgovor na temu

misk0
.: Lugano :. _.: CH :.

SuperModerator
Član broj: 634
Poruke: 2824
*.adsl.ticino.com.

ICQ: 46802502


+49 Profil

icon Re: ExtJS - rejuzabiliti04.07.2009. u 12:18 - pre 180 meseci
Koristim ga vec neko vrijeme za izradu jedne aplikacije ali nisam imao potrebu za tako necim jer su mi gridovi razliciti i malo slicnosti imaju (jednostavno tabelarno prikazivanje sa razlicitim columnModel-ima), a ako bih trebao nesto poput toga sto ti pishes naslijedio bih osnovni Grid (Extend) i onda bi napravio svoju komponentu sa dodatnim parametrima i podesavanjima koju bih kasnije koristio. Tako mislim da bi postigao dobar reusability.
:: Nemoj se svadjati sa budalom, ljudi cesto nece primjetiti razliku ::
 
Odgovor na temu

Mister_rap
SE at Viacom

Član broj: 8822
Poruke: 2540
*.dynamic.sbb.rs.

Jabber: mister_rap@jabber.com


+21 Profil

icon Re: ExtJS - rejuzabiliti04.07.2009. u 13:23 - pre 180 meseci
Ja imam osnovu i neke stvari za generisanje i svaki modul u sistemu ima svoj js u koliko mu je potreban.
Oni dalje imaju svoje add, edit, delete funkcije po potrebi, i naravno grid koji je new Ext.grid.GridPanel...

Posle sa admin masterom dodam taj plugin i to je to.
Na ovaj nacin ima ponvaljanja koda to je neminovno ali sam prezadovoljan strukturom i modifikacije mi se svode na izmenu par linija.

Html koji ti imas smatram suvisnim kod mene je to realizovano ovako pomocu extovog toolbara, za svaki plugin.

Code:

            tbar: [
                    { iconCls: 'icon-refresh', handler: function() { store.reload(); } }, '-',
                    { iconCls: 'icon-add-member', disabled: RO, handler: newMember.createDelegate(this), tooltip: _('Add new member') },
                    { iconCls: 'icon-rem-member', disabled: RO, handler: deleteMember.createDelegate(this), tooltip: _('Remove selected member') },
                    { iconCls: 'icon-edit-member', handler: editMember.createDelegate(this, [  ]), tooltip: _('Edit selected member') }

                ],


U sustini totalno je nebitno za pocetne stvari kako ces da pises kod. Najbitnije je da ga pises sto vise i da se trudis da html eliminises u potpunosti.
E nakon par hiljada linija mozes polako da se posvetis kreiranju tvog admin panela koji ce biti full extJS based :D

Onda ces da naletis na neke probleme i poceti da razmisljas o optimizaciji i stvarnom rejuzabilitiju jer bitnija ti je po mom licnom misljenju backend logika...

Tako da za taj cms u toj aplha fazi mozes da zaobidjes extJS recimo i ubacis ga u beti ili u stable verziji recimo :D
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-1.sezampro.yu.



+33 Profil

icon Re: ExtJS - rejuzabiliti04.07.2009. u 20:22 - pre 180 meseci
Ok, hvala na savetima...

Nego, ipak sam rešio da idem sa izvođenjem svakog grida iz GridPanel klase, jer svaki od njih unosi neke specifičnosti. Jedino što sam još dodao je jedna pomoćna factory metoda, koja mi vraća HttpProxy sa parametrima koji su zajednički za svaki grid:
Code:
function getGridsProxy(config) {
    return new Ext.data.HttpProxy(Ext.apply({
        url: $('#base_url').val() + '/front-end/admin_show_grids_handler.php',
        method: 'POST'
    }, config));
}

I posle pri instanciranju store-a u gridu za proxy ide:
Code:
store: new Ext.data.Store({
    id: 'dataStore',
    proxy: getGridsProxy(),
//itd.

Ne znam kol'ko je sve to ok sa stanovišta nekih standarda pisanja ExtJS koda, al' meni to za sada obavlja posao...

btw Zaglavio sam se kod jednog glupog problema, pri pokušaju da implementiram toggle dugme show/hide detalja u grid-u. Evo dela koda:
Code:
viewConfig: {
    forceFit:true,
    enableRowBody:true,
    showPreview:true,
    getRowClass: function(record, rowIndex, p, store) {
        if (this.showPreview) {
            p.body = '<div style = "margin-left: 3px;">
                           <p>' + record.data.text + '</p> 
                           <p style = " padding-top: 2px; border-top: 1px dashed;">
                              In ' + record.data.WFItemTitle + ', ' + record.data.datetime.dateFormat('d/m/Y, H:i') + '
                           </p>
                      </div>';
            return 'x-grid3-row-expanded';
        }
        return 'x-grid3-row-collapsed';
    }
}

A problem je zapravo ovde, u tbar-u:
Code:
{
    pressed: true,
    enableToggle: true,
    text: 'Details',
    tooltip: 'Show/hide text of a comment.',
    cls: 'x-btn-text-icon details',
    toggleHandler: function(btn, pressed) {
        var view = this.getView(); //Ovo NE radi!
        view.showPreview = pressed;
        view.refresh();
    }
}

Stalno dobijam "this.getView is not a function" u Firebug-u... Gde grešim?
 
Odgovor na temu

misk0
.: Lugano :. _.: CH :.

SuperModerator
Član broj: 634
Poruke: 2824
*.adsl.ticino.com.

ICQ: 46802502


+49 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 01:28 - pre 180 meseci
this se u tom zadnjem slucaju odnosi na button ili??

ako je to, pa imas u pozivu funkcije - btn pa koristi to. Ako ne dobijas tu referencu, probaj sa Extjs.fly ili Extjs.getCmp

:: Nemoj se svadjati sa budalom, ljudi cesto nece primjetiti razliku ::
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
77.105.18.*



+33 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 09:10 - pre 180 meseci
Ne, this se u tom slučaju odnosi na ceo grid. Ideja je da dohvatim njegov view i set-ujem ono showPreview = pressed, a to onda utiče na onaj kod iznad: if (this.showPreview), itd.
 
Odgovor na temu

Mister_rap
SE at Viacom

Član broj: 8822
Poruke: 2540
*.dynamic.sbb.rs.

Jabber: mister_rap@jabber.com


+21 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 13:10 - pre 180 meseci
Ovako ti on ne puca na grid.
Idi sa grid.getView(); to bi trebalo da radi...
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-3.sezampro.yu.



+33 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 13:58 - pre 180 meseci
Ali to grid mi ne postoji, jer ja radim taj deo pri definisanju klase, evo ceo kod (pobrisao sam sad neke delove da bih skratio kod):
Code:
WFAdminManage.commentsGrid = Ext.extend(Ext.grid.GridPanel, {
    initComponent:function() {
        this.sm = new Ext.grid.CheckboxSelectionModel(),
        Ext.apply(this, {
            el:'comments_grid',
            width:730,
            height:560,
            store: //definisanje data store-a,
            
            columns: [
                //kolone
            ],
            
            disableSelection:true,
            sm: this.sm,
            
            viewConfig: {
                forceFit:true,
                enableRowBody:true,
                showPreview:true,
                getRowClass: function(record, rowIndex, p, store) {
                    if (this.showPreview) {
                        p.body = '
                                                <div style = "margin-left: 3px;"> 
                                                  <p>' + record.data.text + '</p> 
                                                  <p style = " padding-top: 2px; border-top: 1px dashed;">
                                                      In ' + record.data.WFItemTitle + ', ' + record.data.datetime.dateFormat('d/m/Y, H:i') + '
                                                  </p> 
                                                </div>';
                        return 'x-grid3-row-expanded';
                    }
                    return 'x-grid3-row-collapsed';
                }
            },
            
            tbar: [
                //neka dugmad pre ovoga

                {
                    pressed: true,
                    enableToggle: true,
                    text: 'Details',
                    tooltip: 'Show/hide text of a comment.',
                    cls: 'x-btn-text-icon details',
                    toggleHandler: function(btn, pressed) {
                        var view = this.getView(); //Ova linija ne radi...
                        view.showPreview = pressed;
                        view.refresh();
                    }
                }
            ],
           
        });
        
        this.bbar = new Ext.PagingToolbar({
            pageSize: 20,
            store: this.store,
            displayInfo: true,
            displayMsg: 'Displaying comments {0} - {1} of {2}',
            emptyMsg: 'There is no any comment in your webfolio.'
        });
 
        WFAdminManage.commentsGrid.superclass.initComponent.apply(this, arguments);
    },
 
    onRender:function() {
        this.store.load({params:{start:0, limit:20}});
 
        WFAdminManage.commentsGrid.superclass.onRender.apply(this, arguments);
    },

});

btw U onom prvom kodu kojeg sam poslao sam išao sa grid.getView(), i to je radilo, zato što sam to pisao u trenutku pravljenja grid-a (grid = new Ext.grid.GridPanel, itd.), a sad ne znam kako to da uradim u ovoj definiciji klase... :S Možda mogu nekako preko tog btn da pristupim grid-u, nešto npr. btn.parentGrid, ne znam...

offTopic: Jeste primetili da ne rade ovi bbCode linkovi sa leve strane...
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-3.sezampro.yu.



+33 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 19:07 - pre 180 meseci
Evo šta sam sve još pokušavao, al' nikako ne ide...

Prvo, pošto je taj problem vezan za scope, tj. onaj opseg važenja, polušao sam da pri kreiranju tog button-a izmenim onaj parametar scope, koji je automatski set-ovan na to dugme koje se kreira, ovako:
Code:

{
   pressed: true,
   enableToggle: true,
   text: 'Details',
   tooltip: 'Show/hide text of a comment.',
   cls: 'x-btn-text-icon details',
   scope: this,
   toggleHandler: function(btn, pressed) {
      var viev = this.getView();
      view.showPreview = pressed;
      view.refresh();
   }
}

Al' ne pomaže... Onda sam pokušao da u tom toggleHandler-u, sa onom findParentByClass metodom dohvatim ovaj moj grid, ovako:
Code:
toggleHandler: function(btn, pressed) {
      var viev = btn.findParentByClass('GridPanel').getView();
      view.showPreview = pressed;
      view.refresh();
}

Al' opet ništa... Pokušao sam čak da najpre ovom mom grid-u dodelim neki id, pre samog render-ovanja grida:
Code:
Ext.onReady(function() {
    Ext.QuickTips.init();
    
    var commentsGrid = new WFAdminManage.commentsGrid();
    Ext.id('grid', commentsGrid);
    commentsGrid.render();
});

... pa da onda posle u onom toggleHandler-u idem ovako:
Code:
toggleHandler: function(btn, pressed) {
      var viev = Ext.get('grid').getView();
      view.showPreview = pressed;
      view.refresh();
}

Al' ni to nema efekta... Stvarno ne znam šta da još pokušam...
 
Odgovor na temu

misk0
.: Lugano :. _.: CH :.

SuperModerator
Član broj: 634
Poruke: 2824
*.adsl.ticino.com.

ICQ: 46802502


+49 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 19:54 - pre 180 meseci
Dodjelis gridu ID (kao sto si vec uradio) i onda uradis Extjs.getCmp('id_grida').method..

:: Nemoj se svadjati sa budalom, ljudi cesto nece primjetiti razliku ::
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-3.sezampro.yu.



+33 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 20:04 - pre 180 meseci
E pa da, pokušao sam naravno sa getCmp, slučajno sam u mom post-u napisao samo get, al' neće ni to...
 
Odgovor na temu

misk0
.: Lugano :. _.: CH :.

SuperModerator
Član broj: 634
Poruke: 2824
*.adsl.ticino.com.

ICQ: 46802502


+49 Profil

icon Re: ExtJS - rejuzabiliti05.07.2009. u 21:46 - pre 180 meseci
Pokusao sa Extjs.fly?
:: Nemoj se svadjati sa budalom, ljudi cesto nece primjetiti razliku ::
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
93.86.137.*



+33 Profil

icon Re: ExtJS - rejuzabiliti06.07.2009. u 11:01 - pre 180 meseci
Nisam to pokušavao, a i nisam siguran da bih s tom f-jom mogao i šta da uradim...
 
Odgovor na temu

Mister_rap
SE at Viacom

Član broj: 8822
Poruke: 2540
*.dynamic.sbb.rs.

Jabber: mister_rap@jabber.com


+21 Profil

icon Re: ExtJS - rejuzabiliti06.07.2009. u 16:43 - pre 180 meseci
Ja stvarno nemam vremena da analiziram detaljnije kod pa ni da ga testiram.
Ali ostaje ti ili da se cimas oko toga ili da probas da o5 napises to (meni ovo drugo u bilo cemu da kucam redovno upali)
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
79.101.91.*



+33 Profil

icon Re: ExtJS - rejuzabiliti06.07.2009. u 17:59 - pre 180 meseci
Ma ovo prvo što sam probao sa promenom scope-a bi sigurno trebalo da radi, ali sam ja tu stavio scope: this, a to this se opet NE odnosi na grid, već na taj toolbar na koji "lepim" dugme. Nemam sad vremena, al' isprobaću danas, sutra još par varijanti s tim...
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
79.101.163.*



+33 Profil

icon Re: ExtJS - rejuzabiliti08.07.2009. u 15:18 - pre 180 meseci
Evo danas sam sasvim slučajno opet probao ono sa scope: this, i sada, za razliku od prethodnog puta - radi. :) Neverovatno... :S
 
Odgovor na temu

[es] :: Javascript i AJAX :: ExtJS - rejuzabiliti

[ Pregleda: 1453 | Odgovora: 15 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.