2012年7月18日 星期三

Sencha Touch 2 : Model

一.Model功能
1.定義資料架構
model被用來定義在應用程式中所要使用的資料架構,也就是說定義好model內的資料欄位(field)將取得的資料包裝成model物件後,就可以用model所提供的方法來操作
2.與Store配合使用
model大多與store一起使用,當store使用proxy載入資料後,會將資料轉成model物件,model本身也可以定義proxy,自行載入資料,但比較不建議這樣使用,因Store可以透過Ext.getStore()讓store可以在各個地方使用,model則沒辦法,主要還是把model當作資料架構定義與資料內容驗證用
3.Ext.data.Model包含了四個部分 
  • Fields:欄位定義 
  • Proxies:設定取資料用proxy
  • Associations:設定model間關聯性
  • Validations:驗證
二.欄位(fields)
當由server取到json物件要儲存到model欄位
若要儲存到欄位的資料為物件,type可設定為auto
在tmpl內要取用欄位資料用{xxx.xxx}方式往下讀取即可

Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'id',   type: 'int'},
            {name: 'name', type: 'string'},
            {name: 'obj', type: 'auto'},
        ]        
    }
});

三.驗證Validations
對指定的欄位設定驗證規則
在validastions內可設定多條規則
每筆包含type:驗證項目,field:要驗證的欄位
type可使用的值為
  • presence:檢查是否有值,0是有效的,空值則無效
  • length:可設定最長(max),或最少(min)字元
  • format:檢查字串形式,用reg express檢查
  • inclusion:設定允許使用的字串
  • exclusion:設定不允許使用的字串
Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'id',   type: 'int'},
            {name: 'name', type: 'string'},
            {name: 'obj', type: 'auto'},
        ],
        validations: [
            { type: 'presence', field: 'id' },
            { type: 'presence', field: 'name', message: '不可空白'}                    
        ]    
    }
});

四.關聯Associations
設定好關聯性可以讓model內可包含其他的model
可以在取得資料後,把資料塞到各階層的model內
如果不使用關聯性設定,欄位的內容只是一個object
使用關聯性設定可以讓欄位內容是一個model
1.設定關聯性範例
Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'id',   type: 'int'},
            {name: 'name', type: 'string'}
        ],        
        hasMany: {model: 'Product', name: 'products'}
    }
});
代表User內有一個products屬性,這個屬性內儲存著Product Model的Array

2.使用關聯性範例
User.load(1, {
    success: function(user) {
        console.log("User: " + user.get('name'));
        user.posts().each(function(post) {            
            console.log(post.get('title'));//post本身即是一個model
            post.comments().each(function(comment) {//post內的comment也是一個model
                console.log(comment.get('message'));
            });
        });
    }
});    
3.當model有設定belongTo,就可以取得其上層model instance

Ext.define('User', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'id',   type: 'int'},
            {name: 'name', type: 'string'}
        ],        
        hasMany: {model: 'Post', name: 'prosts'}
    }
});
Ext.define('Post', {
    extend: 'Ext.data.Model',
    config: {
        fields: [
            {name: 'id',   type: 'int'},
            {name: 'name', type: 'string'}
        ],        
        belongsTo: 'User'
    }
});
post.getUser(function(user) {//非同步,要透過callback取得user
    console.log('post: ' + user.get('name'))
});    

五.id屬性
若model內的data值有id,這id值也會被copy到model上產生internalId值
當model.getId()會取到這internalId值
若有用idProperty指定哪個欄位當id值,則該欄位會被copy到internalId
若資料內沒id值,也沒設定idProperty,就會用系統自己產生的id值

Ext.define("Stest.model.ItemModel", {
    extend: "Ext.data.Model",
    config: {
        idProperty: 'firstName',
        fields: [
            { name: 'firstName', type: 'string' },
            { name: 'lastName', type: 'string'}                   
        ]        
    }
});
注意:當作localStorage Store使用的model,不可使用id field,必須由系統產生
否則無法儲存到localStorage上

六.載入資料
model要執行load必須透過Class執行,且執行結果必須要是array,若不是,同樣需要在rootProperty內先處理
Ext.define("Stest.model.ItemModel", {
    extend: "Ext.data.Model",
    config: {
        idProperty: 'firstName',
        fields: [
            { name: 'firstName', type: 'string' },
            { name: 'lastName', type: 'string'}                
        ]      
    }
});

七.使用資料
  1. model.raw取到原始資物物件
  2. model.getData()取到修改過的資料物件
  3. model.get('欄位名稱')取到指定欄位值

沒有留言: