2012-08-02 32 views
2

難以理解模型的「關聯」特性以及開發人員如何通過關聯訪問嵌套數據。如何訪問Extjs嵌套模型(從Xml加載)?

這是我們試圖解析的一個簡單的XML文件。

<?xml version="1.0" encoding="UTF-8"?> 
<contacts> 
    <contact> 
     <id>1</id> 
     <name>Bob Jones</name> 
     <emails> 
      <email> 
       <addr>[email protected]</addr> 
       <display>B. Jones 1</display> 
      </email> 
      <email> 
       <addr>[email protected]</addr> 
       <display>B. Jones 2</display> 
      </email> 
     </emails> 
    </contact> 
    <contact> 
     <id>2</id> 
     <name>John Rodeo</name> 
     <emails> 
      <email> 
       <addr>[email protected]</addr> 
       <display>J. Rodeo 1</display> 
      </email> 
      <email> 
       <addr>[email protected]</addr> 
       <display>J. Rodeo 2</display> 
      </email> 
     </emails> 
    </contact> 
</contacts> 

而這裏的相關模型

Ext.define('MyApp.model.Contact', { 
    extend: 'Ext.data.Model', 
    uses: [ 
     'MyApp.model.Emails' 
    ], 

    fields: [ 
     { 
      name: 'id' 
     }, 
     { 
      name: 'name' 
     } 
    ], 

    hasMany: { 
     model: 'MyApp.model.Emails', 
     autoLoad: true, 
     foreignKey: 'addr', 
     name: 'emailAddresses' 
    } 
}); 

Ext.define('MyApp.model.Emails', { 
    extend: 'Ext.data.Model', 
    uses: [ 
     'MyApp.model.Contact' 
    ], 

    idProperty: 'addr', 

    fields: [ 
     { 
      name: 'addr' 
     }, 
     { 
      name: 'display' 
     } 
    ], 

    belongsTo: { 
     model: 'MyApp.model.Contact' 
    } 
}); 

最後,這裏的商店:

Ext.define('MyApp.store.MyXmlStore', { 
    extend: 'Ext.data.Store', 
    requires: [ 
     'MyApp.model.Contact' 
    ], 

    constructor: function(cfg) { 
     var me = this; 
     cfg = cfg || {}; 
     me.callParent([Ext.apply({ 
      autoLoad: true, 
      storeId: 'MyXmlStore', 
      model: 'MyApp.model.Contact', 
      proxy: { 
       type: 'ajax', 
       url: 'data/data.xml', 
       reader: { 
        type: 'xml', 
        record: 'contact' 
       } 
      } 
     }, cfg)]); 
    } 
}); 

我們創建了一個簡單的網格,並將其鏈接到商店......和急, 它顯示的聯繫人(快速ascii渲染)

+---------------------------+ 
| My Grid Panel    | 
+-----+---------------------+ 
| Id | Name    | 
+-----+---------------------+ 
| 1 | Bob Jones   | 
| 2 | John Rodeo   | 

但是,我們完全喪失瞭如何檢索關聯電子郵件 記錄。

我讀過GridPanel可能無法正確呈現關聯的 數據。這對我們來說沒有問題 - 我們只是想方設法地使用這個模擬數據來編程式地訪問我們的 。

例如,假設我們想創建一個附加 商店簡單onXmlstoreLoad事件,我們想只是CONSOLE.LOG()加載 後的電子郵件地址 - 什麼是正確的語法?

我們試圖推薦的方法:

onXmlstoreLoad: function(store, records, successful, operation, options) { 
    console.log(store.emailAddresses.getAt(0)); 
} 

但是這會導致一個未定義的參考。

我認識到它可能歸結爲我們錯誤地描述我們的模型,但我們已經嘗試了 許多不同的配置,並且無法確定問題 是否數據沒有進入商店...或者我們是否不能參考是句法正確的 。

回答

2

終於搞清楚我錯過了什麼才能正確讀取嵌套模型。一旦我們正確地填充我們的商店,訪問嵌套的數據記錄是一件簡單的事情。

我們缺少的關鍵是代理/閱讀器。每個模型需要有自己的代理閱讀器,以便您可以指定「記錄」和「根」參數。

我建議任何人在這個線程中絆倒檢查由Neil McGuigan維護的優秀網站 - http://extjs-tutorials.blogspot.com/2012_05_01_archive.html。有許多重要的提示你應該遵循的最佳做法。

尼爾提供給我們的解決方案的一條重要線索是開發人員應該將代理和讀者關閉模型,而不是關閉商店。這使得管理Xml特定記錄/根參數變得很簡單。

對於任何第一次進入Extjs深處的人來說,這是一個艱難的任務,我強烈建議您與Firebug親密接觸。進入extjs源代碼開始回答關於各個位如何組合在一起的許多重要問題。

extjs代碼庫的記錄非常完善。雖然開發人員顯然是使用Javascript的黑帶,但偶爾會使他們成爲跟隨他們前進的挑戰,最終的結果是非常值得的。

如果你正在尋找工作的代碼...

我們店裏

Ext.define('MyApp.store.MyXmlStore', { 
    extend: 'Ext.data.Store', 
    requires: [ 
     'MyApp.model.Contact' 
    ], 

    constructor: function(cfg) { 
     var me = this; 
     cfg = cfg || {}; 
     me.callParent([Ext.apply({ 
      autoLoad: true, 
      storeId: 'MyXmlStore', 
      model: 'MyApp.model.Contact', 
      listeners: { 
       load: { 
        fn: me.onXmlstoreLoad, 
        scope: me 
       } 
      } 
     }, cfg)]); 
    }, 

    onXmlstoreLoad: function(store, records, successful, operation, options) { 
     console.log("onXmlstoreLoad:"+ successful); 
     console.log(s.getAt(0).emailAddressesStore.getAt(0)); 

    } 

}); 

而我們的模型

Ext.define('MyApp.model.Contact', { 
    extend: 'Ext.data.Model', 
    uses: [ 
     'MyApp.model.Emails' 
    ], 

    fields: [ 
     { 
      mapping: 'id', 
      name: 'id', 
      type: 'int' 
     }, 
     { 
      mapping: 'name', 
      name: 'name', 
      type: 'string' 
     } 
    ], 

    hasMany: { 
     associationKey: 'emails', 
     model: 'MyApp.model.Emails', 
     name: 'emailAddresses' 
    }, 

    proxy: { 
     type: 'ajax', 
     url: 'data/data.xml', 
     reader: { 
      type: 'xml', 
      root: 'contacts', 
      record: 'contact' 
     } 
    } 
}); 
Ext.define('MyApp.model.Emails', { 
    extend: 'Ext.data.Model', 
    uses: [ 
     'MyApp.model.Contact' 
    ], 

    fields: [ 
     { 
      mapping: 'addr', 
      name: 'addr', 
      type: 'string' 
     }, 
     { 
      mapping: 'display', 
      name: 'display', 
      type: 'string' 
     } 
    ], 

    proxy: { 
     type: 'ajax', 
     url: 'data/data.xml', 
     reader: { 
      type: 'xml', 
      root: 'emails', 
      record: 'email' 
     } 
    }, 

    belongsTo: { 
     model: 'MyApp.model.Contact' 
    } 
}); 
+0

感謝榮譽:) – 2013-07-02 03:42:10

+0

同樣的問題,做得好... – 2015-08-14 22:20:31