EXTJS4——为什么不&x27;我的关联存储是否加载子数据?
我有一个父母和孩子的商店,如图所示: 父模型EXTJS4——为什么不&x27;我的关联存储是否加载子数据?,extjs,extjs4,extjs-mvc,Extjs,Extjs4,Extjs Mvc,我有一个父母和孩子的商店,如图所示: 父模型 Ext.define('APP.model.Client', { extend: 'Ext.data.Model', requires: [ 'APP.model.Website', 'Ext.data.association.HasMany', 'Ext.data.association.BelongsTo'], fields: [{ name: 'id', type: 'st
Ext.define('APP.model.Client', {
extend: 'Ext.data.Model',
requires: [
'APP.model.Website', 'Ext.data.association.HasMany', 'Ext.data.association.BelongsTo'],
fields: [{
name: 'id',
type: 'string'
}, {
name: 'name',
type: 'string'
}, {
name: 'slug',
type: 'string'
}, {
name: 'active',
type: 'boolean'
}, {
name: 'current',
type: 'boolean'
}],
hasMany: {
model: 'APP.model.Website',
name: 'websites'
}
});
Ext.define('APP.model.Website', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
}, {
name: 'client_id',
type: 'string'
}, {
name: 'sub_domain',
type: 'string'
}, {
name: 'active',
type: 'boolean'
}],
belongsTo: 'APP.model.Client'
});
子模型
Ext.define('APP.model.Client', {
extend: 'Ext.data.Model',
requires: [
'APP.model.Website', 'Ext.data.association.HasMany', 'Ext.data.association.BelongsTo'],
fields: [{
name: 'id',
type: 'string'
}, {
name: 'name',
type: 'string'
}, {
name: 'slug',
type: 'string'
}, {
name: 'active',
type: 'boolean'
}, {
name: 'current',
type: 'boolean'
}],
hasMany: {
model: 'APP.model.Website',
name: 'websites'
}
});
Ext.define('APP.model.Website', {
extend: 'Ext.data.Model',
fields: [{
name: 'id',
type: 'string'
}, {
name: 'client_id',
type: 'string'
}, {
name: 'sub_domain',
type: 'string'
}, {
name: 'active',
type: 'boolean'
}],
belongsTo: 'APP.model.Client'
});
通过服务器使用AJAX调用,我正在加载客户机
存储,这很好。但是网站
存储区没有填充,当我在客户端
存储on.load函数上断点时,要查看填充的内容,客户端
存储区仅填充客户端数据,但在该存储区的原始
属性中,我可以看到所有网站
数据。因此它被正确返回,但我的extjs不正确。以下是商店:
客户商店
Ext.define('APP.store.Clients', {
extend: 'Ext.data.Store',
autoLoad: false,
model: 'APP.model.Client',
proxy: {
type: 'ajax',
url: '/client/list',
reader: {
type: 'json',
root: 'items'
}
},
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
Ext.define('APP.store.Websites', {
extend: 'Ext.data.Store',
requires: ['Ext.ux.Msg'],
autoLoad: false,
model: 'APP.model.Website',
proxy: {
type: 'ajax',
url: '/client/list',
reader: {
type: 'json',
root: 'items'
},
writer: {
type: 'json'
}
},
sorters: [{
property: 'sub_domain',
direction: 'ASC'
}]
});
网站商店
Ext.define('APP.store.Clients', {
extend: 'Ext.data.Store',
autoLoad: false,
model: 'APP.model.Client',
proxy: {
type: 'ajax',
url: '/client/list',
reader: {
type: 'json',
root: 'items'
}
},
sorters: [{
property: 'name',
direction: 'ASC'
}]
});
Ext.define('APP.store.Websites', {
extend: 'Ext.data.Store',
requires: ['Ext.ux.Msg'],
autoLoad: false,
model: 'APP.model.Website',
proxy: {
type: 'ajax',
url: '/client/list',
reader: {
type: 'json',
root: 'items'
},
writer: {
type: 'json'
}
},
sorters: [{
property: 'sub_domain',
direction: 'ASC'
}]
});
我的最终结果是…我想填充这两个存储,这样我可以单击一个元素,当它从父存储加载某些内容时,我可以访问子存储(当我解决这个问题时会有更多),以填充选项卡中的一对网格
就我的设置而言,我遗漏了什么?几天前我刚下载了extjs4,所以我现在使用4.1 你的假设是错误的。您希望网站存储自行加载,但实际情况并非如此。您可以执行以下操作(这未经测试,但我在所有项目中都是这样做的): 在客户端网格中,为itemclick事件添加侦听器以调用以下方法(showWebSites)。它将接收包含所选APP.model.client实例的所选客户端记录。然后,假设每个客户端都有一组网站,该方法将加载APP.store.WebSites商店,客户端的网站将显示在您的视图中
showWebSites: function (sender, selectedClient) {
Ext.StoreManager.lookup('APP.store.Websites')
.loadData(selectedClient.data.WebSites);
}
就是这样。我希望您觉得它有用。将代理放在模型中,除非您有充分的理由不[1]
确保在同一文件中或应用程序的早期版本中,您需要相关型号
如果您想随意加载相关数据(即,在以后的网络请求中),请使用foreignKey
如果在相同(嵌套)响应中加载了相关数据,请使用associationKey
或者两者兼用
始终name
您的关系(否则,如果使用名称空间,名称将很奇怪)
在关系中,始终为model
属性使用完全限定的模型名称
工作代码:
model/Contact.js
:
Ext.define('Assoc.model.Contact', {
extend:'Ext.data.Model',
requires:[
'Assoc.model.PhoneNumber'
],
fields:[
'name' /* automatically has an 'id' field */
],
hasMany:[
{
model:'Assoc.model.PhoneNumber', /*use the fully-qualified name here*/
name:'phoneNumbers',
foreignKey:'contact_id',
associationKey:'phoneNumbers'
}
],
proxy:{
type:'ajax',
url:'assoc/data/contacts.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.define('Assoc.model.PhoneNumber', {
extend:'Ext.data.Model',
fields:[
'number',
'contact_id'
],
proxy:{
type:'ajax',
url:'assoc/data/phone-numbers.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.Loader.setConfig({
enabled:true
});
Ext.application({
requires:[
'Assoc.model.Contact'
],
name:'Assoc',
appFolder:'Assoc',
launch:function(){
/* load child models that are in the response (uses associationKey): */
Assoc.model.Contact.load(1, {
success: function(record){
console.log(record.phoneNumbers());
}
});
/* load child models at will (uses foreignKey). this overwrites child model that are in the first load response */
Assoc.model.Contact.load(1, {
success: function(record){
record.phoneNumbers().load({
callback:function(){
console.log(arguments);
}
});
}
});
}
});
model/PhoneNumber.js
:
Ext.define('Assoc.model.Contact', {
extend:'Ext.data.Model',
requires:[
'Assoc.model.PhoneNumber'
],
fields:[
'name' /* automatically has an 'id' field */
],
hasMany:[
{
model:'Assoc.model.PhoneNumber', /*use the fully-qualified name here*/
name:'phoneNumbers',
foreignKey:'contact_id',
associationKey:'phoneNumbers'
}
],
proxy:{
type:'ajax',
url:'assoc/data/contacts.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.define('Assoc.model.PhoneNumber', {
extend:'Ext.data.Model',
fields:[
'number',
'contact_id'
],
proxy:{
type:'ajax',
url:'assoc/data/phone-numbers.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.Loader.setConfig({
enabled:true
});
Ext.application({
requires:[
'Assoc.model.Contact'
],
name:'Assoc',
appFolder:'Assoc',
launch:function(){
/* load child models that are in the response (uses associationKey): */
Assoc.model.Contact.load(1, {
success: function(record){
console.log(record.phoneNumbers());
}
});
/* load child models at will (uses foreignKey). this overwrites child model that are in the first load response */
Assoc.model.Contact.load(1, {
success: function(record){
record.phoneNumbers().load({
callback:function(){
console.log(arguments);
}
});
}
});
}
});
data/contacts.json:
{
"data":[
{
"id":1,
"name":"neil",
"phoneNumbers":[
{
"id":999,
"contact_id":1,
"number":"9005551234"
}
]
}
]
}
data/phone-numbers.json
{
"data":[
{
"id":7,
"contact_id":1,
"number":"6045551212"
},
{
"id":88,
"contact_id":1,
"number":"8009996541"
},
]
}
app.js
:
Ext.define('Assoc.model.Contact', {
extend:'Ext.data.Model',
requires:[
'Assoc.model.PhoneNumber'
],
fields:[
'name' /* automatically has an 'id' field */
],
hasMany:[
{
model:'Assoc.model.PhoneNumber', /*use the fully-qualified name here*/
name:'phoneNumbers',
foreignKey:'contact_id',
associationKey:'phoneNumbers'
}
],
proxy:{
type:'ajax',
url:'assoc/data/contacts.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.define('Assoc.model.PhoneNumber', {
extend:'Ext.data.Model',
fields:[
'number',
'contact_id'
],
proxy:{
type:'ajax',
url:'assoc/data/phone-numbers.json',
reader:{
type:'json',
root:'data'
}
}
});
Ext.Loader.setConfig({
enabled:true
});
Ext.application({
requires:[
'Assoc.model.Contact'
],
name:'Assoc',
appFolder:'Assoc',
launch:function(){
/* load child models that are in the response (uses associationKey): */
Assoc.model.Contact.load(1, {
success: function(record){
console.log(record.phoneNumbers());
}
});
/* load child models at will (uses foreignKey). this overwrites child model that are in the first load response */
Assoc.model.Contact.load(1, {
success: function(record){
record.phoneNumbers().load({
callback:function(){
console.log(arguments);
}
});
}
});
}
});
[1] 商店将使用其模型的代理。如果需要,您始终可以覆盖商店的代理。如果模型没有代理,您将无法使用Model.load()。当您使用关联时,extjs不使用您的网站存储。相反,它创建了自己的普通存储。有关更多信息,请查看我的答案。以您的示例为例,似乎我需要执行
selectedClient.websites().load()
,但我面临同样的问题。相关数据没有正确加载到存储/模型中(请注意我对下面答案的评论),因此我得到错误对象没有方法“网站”
。当数据从服务器返回时,它没有正确加载到模型/存储中,因此其中一个存在配置问题。然后当我将hasMany:{model:'Website',name:'websites'}
更改为hasMany:{model:'APP.model.Website',name:'websites'}
我收到一个新错误无法调用未定义的方法“indexOf”
。看起来它正在识别websites()方法,但我现在有一个新错误。我将逐步查看调试文件以尝试查看发生了什么。运行此selectedClient.websites().load()
时,它似乎找到了带有websites()
的正确存储,但代理中没有配置URL。正如您在上面的定义中所看到的,实际上我在代理服务器上配置了一个URL…这是有意义的,但是selectedClient.data.websites
中没有包含任何内容。但是,数据在selectedClient.raw.websites
中,它告诉我数据正在从服务器返回,但没有正确加载。因此,我的模型/商店中的某些内容不正确。我要补充的是,使用selectedClient.raw.websites
加载它是可行的,但似乎不是正确的解决方案感谢notes&code示例。这真的很有帮助!我注意到你的电话号码模型中没有使用belongsTo
。如果父模型是按您现有的方式配置的,则无需使用belongsTo。如果您试图从子模型引用父模型,则只需使用belongsTo。你不需要它从父母那里引用孩子。谢谢你的解决方案帮助我找到了我的问题。注意从ArrayStore派生存储类,即扩展:“Ext.data.ArrayStore”。您将得到一个Ext.data.reader.Array
,它将悄悄地覆盖您配置的Json读取器,并在加载嵌套数据时让您挠头数小时,但您的父数据尚未初始化。