2014年3月19日 星期三

Extjs 使用 loadData 會對應不到 mapping 的值之解決方法

我先前有針對 Combo 連動作一篇解說:ASP.NET MVC 4 WebApi 與 Extjs 的結合 -- Combo 連動

我在做四層 Combo 資料連動時發現了這個問題,一般連動選單項目時,如果顯示的內容和值在同一層 json 裡面不會有問題,這個問題發生在如果顯示的內容與值是在內嵌欄位時,資料會對應錯誤而導致顯示不出來

先看原本從 API 傳過來的資料 ( 已經過刪減,註解部分為後來加上 ):
"JobLevel": [
    "Id": "1",
    "Code": "T1", 
    {
        "JobGroupMapping": [ 
            {
                "Id": "1",
    
                ...
                // 顯示資料
                "JobGroup": {
                    "Id": "1",
                    "Language_Name": "工程師" 
                },
                // 連動資料
                "JobTitle": [
                        {
                            "Id": "1",
                  
                            // ...
                  
                            "Language_Name": "工程師"
                        },
                        {
                            "Id": "2",
      
                            // ...
      
                            "Language_Name": "資深工程師"
                        },
                        {
                            "Id": "3",
      
                             // ...
      
                            "Language_Name": "主任工程師"
                        }
                ]
            }
        ]
    }
]

而我這兩張表的 Extjs Model 為:
Ext.define('JobLevel', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'Id', type: 'string' },
        { name: 'Language_Name', type: 'string' }
    ],
    hasMany: { model: 'JobGroupMapping', name: 'JobGroupMapping' }
});

Ext.define('JobGroupMapping', {
    extend: 'Ext.data.Model',
    fields: [
        { name: 'Id', type: 'string' },
        { name: 'JobGroupId', type: 'string', mapping: 'JobGroup.Id' },
        { name: 'Language_Name', type: 'string', mapping: 'JobGroup.Language_Name' }
    ],
    belongsTo: 'JobLevel'
});

mapping 的意思就是將內嵌 json 的值拉到同一層對應成另外名稱,有別名的意味。選項選取時,就必須設定連動選項的資料內容,這裡我是使用 loadData 將下一層資料帶入 :
{
    itemId: 'field_joblevel',
    name: 'JobLevel.Id',
    editable: false,
    store: storeJobLevel,
    xtype: 'combobox',
    fieldLabel: 'JobLevel',
    queryMode: 'local',
    valueField: 'Id',
    displayField: 'Code',
    listeners: {
        change: function (combo, aNew, aOld) {
            var record = this.findRecord(this.valueField, aNew);
            JobGroupMapping.loadRawData(record.raw.JobGroupMapping);
            var tCombo = this.up('form').getComponent('field_jobgroup');
            tCombo.setValue(tCombo.getStore().getAt(0).get(tCombo.valueField));
        }
    }
},
{
    itemId: 'field_jobgroup',
    name: 'JobGroup.Id',
    editable: false,
    store: JobGroupMapping,
    xtype: 'combobox',
    fieldLabel: 'JobGroup',
    queryMode: 'local',
    valueField: 'Id',
    displayField: 'Language_Name'
}

此時問題發生了,我在選擇 JobLevel 的這個選項,接著會對應不到 JobGroup 這個選項。

後來我研究與參考了一下網路上的資料,發現有另外一個方法可以解決這問題 -- loadRawData,比較一下這兩個方法,此時才了解連動時必須要注意此情況:

loadRawData

Loads data via the bound Proxy's reader
Use this method if you are attempting to load data and want to utilize the configured data reader

loadData

Loads an array of data straight into the Store.

Using this method is great if the data is in the correct format already (e.g. it doesn't need to be processed by a reader). If your data requires processing to decode the data structure, use a MemoryProxy or loadRawData.

差異就是 loadRawData 會將資料結構解析,所以沒有問題,但使用 loadData 的前提之下必須要資料都在同一層,否則必須要去使用 MemoryProxy 或者 loadRawData。

參考:Extjs store load json data,store fields mapping can't show dataExt.data.StoreView

沒有留言 :

張貼留言

Related Posts Plugin for WordPress, Blogger...