2012年7月18日 星期三

Sencha Touch 2 : Store 載入資料的後處理

一.需要處理的狀況
當Store取得資料,目標是將資料轉成model Array以方便使用Store提供的功能如find,sorter filter等操作,可能遇到狀況
  1. 取得的資料為物件,只取物件中array的部份產生model array
  2. 載入的資料欄位需要先作一些修改處理,才能存到model內
在做這部份的處理,會使用到Store的rootProperty設定與Store的 load Listener

在載入資料時,rootProperty會先執行,然後才是執行load的listener
load listener內的資料已經是經過rootProperty處理過的資料

二.rootProperty
rootProperty是用在當由Server取得JSON物件資料,用來告訴Store在載入資料後,
由哪個節點開始解析放入model,通常會是節點名稱的字串值,也可以是一個function,
如果取得Server端的JSON已經是個Array,則rootProperty的設定是無效不會被執行到的


以下Store會以資料的users內容產生models
資料來源
{
    meta:{},
    users:[
        {},{}...
    ]
}

Store
Ext.define("My.store.MyStore", {
    extend: "Ext.data.Store",
    config: {
        model: "My.model.UserModel",            
        proxy: {
            type: 'ajax',                       
            reader: {
                type: 'json'              
            }
        },  
        rootProperty:"users"
    }
});

三.Load Event Listener
  1. 在資料載入後,load event會被觸發
    通常對要存入model的欄位值要做改變,可以在load event內做,也可以在rootProperty內處理,
    但最好統一在load event內做,因為如果資料來源是array,rootProperty並不會被執行到,可能會造成錯誤
  2. load evnet內會接收到records 與store參數,要對資料做處理可以使用records這或store來操作都可
  3. load event被觸發時,取得的records是該次fetch取得的資料,而非總資料量

四.回傳值為Array的處理範例
rootProperty不需設定,只要在listener load內處理所要的變化

Ext.define("My.store.MyStore", {
    extend: "Ext.data.Store",
    config: {
        model: "My.model.UserModel",            
        proxy: {
            type: 'ajax',                       
            reader: {
                type: 'json'              
            }
        }
    }
    listeners:{
        load:function(store,records,_success,operation,opts){
            for(var i=0;i
                records[i].set('uid',records[i].get('id'));
                delete records[i].getData().id;
            }
        }
    }    
});

五.回傳為物件的處理方式
rootProperty設定回傳array部份,其他值的變化由load event listener處理

Ext.define("My.store.MyStore", {
    extend: "Ext.data.Store",
    config: {      
        model: "My.model.MyModel",    
        proxy: {
            type: 'ajax',                
            reader: {
                type: 'json',
                rootProperty:function(data){
                    return data.users                    
                }            
            }
        },
        listeners:{
            load:function(store,records,_success,operation,opts){                
                for(var i=0;i
                    records[i].set('uid',records[i].get('id'));
                    delete records[i].getData().id;                    
                }
                //---兩種方式都可以----
                store.each(function(record, index){
                  record.set('index', index);
                },store)
            }
        }
    }
});    

六.處理過後的資料使用
  1. Store如果被加工過,那取資料要由model.getData()取,不要由model.raw取
  2. 要將資料放到其他store內,不要直接將records(models array加進去)  而是由所有model取出資料,放data array而非models array比較安全


listeners:{
    load:function(store,records,_success,operation,opts){
        var _objs=[];
        for(var i=0;i
            records[i].set('uid',records[i].get('id'));
            delete records[i].getData().id;
            _objs.push(records[i].getData())
        }
        var anotherStore=Ext.getStore('AnotherStore');
        localStore.add(_objs);    
    }
}    

沒有留言: