Extjs4:如何在多个商店或模型之间共享数据? [英] Extjs4: How to share data between multiple stores or models?

查看:114
本文介绍了Extjs4:如何在多个商店或模型之间共享数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很陌生,我正在努力找出模特商店和代理商。



服务器返回一个较大的JSON对象。
例如。

  {
responseHeader:{
status:0 ,
QTime:12,
params:{
facet:true,
facet.limit:40
}
},
response:{
numFound:3806,
start:0,
docs:[
{
//很多字段
id:1234,
...
//某些数组属性
testfield:[


],
...
}
]
},
facet_counts:{
facet_queries:{
email:3806
},
facet_fields:{
emailaddress:{
},
:{
candle:136,
filter:130
},
fromemail:{
},
// ...
},
facet_dates:{},
facet_ranges :{}
},
highlighting:{
some doc id:{
emailtext:[电话:blah blah< em> blah< / EM>中],
combined:[< em>电子邮件< / em> To:blah blah blah]
}
}
}

我不想多次加载这个数据,我想从这个对象中获取数据,例如docs对象,并将其放入网格中。然后拉出另一个部件放入一个选择框。



如何加载这些数据一次,然后创建模型和商店来提供网格和选择框?



从我看过的代理中,服务器的响应是?所以我试图创建一个商店的代理外面。想想我可以使用与多个商店相同的代理。

  var myProxy1 = Ext.create('Ext.data.proxy .proxy',{
type:'ajax',
url:'../test',
reader:{
type:'json',
root :'responseHeader'
}
});

但是当我将MyProxy1传递到商店时

  Ext.define('Test',{
extends:'Ext.data.Model',
fields:[
{name:'status ',键入:'int'},
{name:'QTime',type:'int'},
{name:'param',type:'auto'}
]
});

var myStore = Ext.create('Ext.data.Store',{
model:'Test',
proxy:myProxy1,
autoLoad:true,
listeners:{
load:function(ths,records,successful,operation,eOpts){
debugger;
}
}
});

它不工作。加载事件永远不会被触发。没有数据被加载我可以看到代理提出了请求,我看到服务器的响应,但是没有加载。



如果我把代理内联它加载。 / p>

  var myStore = Ext.create('Ext.data.Store',{
model:'Test',
proxy:{
type:'ajax',
url:'../test',
reader:{
type:'json',
root:'responseHeader'
}
},
autoLoad:true,
listeners:{
load:function(ths,records,successful,operation,eOpts){
调试器;
}
}
});

我以为我可以有一个代理,将其附加到多个商店,只是更改读者在我加载商店之前。

解决方案

你几乎在那里,虽然我很确定你是全部了解为了别人的利益,我可以给你一个扩展的答案和一个稍微修改的解决方案来解决你的问题。



说明:




  • 模型 - 主要定义记录的字段。

  • 商店持有一组记录。

  • 代理 - 通过所选方法(Ajax,Direct等)实现服务器通信,并映射CRUD(创建/读/更新/销毁)操作,当相关商店或模型发生变化时,这种结果。

  • 阅读器 - 告诉代理如何解释服务器返回的数据

  • 网格 Combobox - 可以显示商店记录。



您的场景并不罕见 - 而默认情况下,ExtJS加载每个单独存储,应用程序可能希望通过单次读取呼叫立即加载各种存储;例如,当渲染一个依赖于商店的组件依赖于另一个商店时。



您的代码与实现这一点并不遥远,但这里是如何做到的。实际上,当主(Tasks)存储器加载时,服务器响应还携带slave(标签)存储的数据,然后将其手动加载到该slave存储。



奴隶商店(通知 autoload:false ,无读取操作):

  Ext.define('DL.store.Tags',{
extends:'Ext.data.Store',
model:'DL.model.Tag '$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

$ b //注意,任务由TasksStore加载并加载到该商店时,
$ b proxy:{
type:'direct',

api:{
create:Tags.Create,
update:Tags.Update,
destroy:Tags.Destroy,
},

reader:{
type:'json',
root:'tags'
}
},

});

然后主商店:

  Ext.define('DL.store.Tasks',{
extends:'Ext.data.TreeStore',
model:'DL.model.Task' ,

autoLoad:true,
autoSync:true,

root:{
text:'Root',
id:null,
expanded:true
},

proxy:{
type:'direct',

api:{
create :Tasks.Create,
read:Tasks.Read,
update:Tasks.Update,
destroy:Tasks.Destroy,
},

} ,

onProxyLoad:function(aOperation)
{
//任务的读取请求也将返回用户标签
//所以将这些标签放入他们的
var iResult = aOperation.response.result,
iTagsStore = Ext.StoreManager.lookup('Tags');

if(Ext .isDefined(iResult.tags))
iTagsStore.loadRawData(iResult);

//我们需要Tasks存储的这一行来加载自己的数据
this.callParent(arguments);
}
});

基本上它所做的一切都是服务器响应的一部分,并将其手动加载到从属



PHP服务器端代码(用于任务读取操作)涉及:

  return array(
'success'=> true,
'children'=> $ iNodes,
'tags'=> $ iTags
);

其中 children 是读者的根'master'商店,而标签是额外的数据,然后加载到奴隶商店。



我希望您能够将这些概念应用于您的代码。


I'm new to Ext and I'm struggling to figure out Models Stores and Proxies.

The server returns one large JSON object. For example.

{ 
    "responseHeader":{ 
        "status":0, 
        "QTime":12, 
        "params":{ 
            "facet":"true", 
            "facet.limit":"40" 
        }
    },
    "response":{
        "numFound":3806,
        "start":0,
        "docs":[ 
            { 
                //Lots of fields
                "id":"1234",
                ...
                //Some array properties
                "testfield":[ 
                    "",
                    ""
                ],
                ...
            }
        ]
    },
    "facet_counts":{
        "facet_queries":{
            "email":3806
        },
        "facet_fields":{
           "emailaddress":{ 
            },
            "subject":{
                "candles":136,
                "filter":130 
            },
            "fromemail":{ 
            },
           //...
        },
        "facet_dates":{ },
        "facet_ranges":{}
    },
    "highlighting":{
        "some doc id":{
            "emailtext":[ " Tel.: blah blah <em>blah</em>" ],
            "combined":[ "<em>Email</em> To: blah blah blah" ]
        }
    }
}

I don't want to load this data more than once, I want to grab data from this object, for example the docs object, and put it into a grid. Then pull out another part to put into a selectbox.

How do I load this data once, yet create models and stores to give to grids and selectboxes, from it?

From what I read the proxy holds the servers response? So I tried creating a proxy out side of a store. Thinking I could use the same proxy with more than one store.

var myProxy1 = Ext.create('Ext.data.proxy.Proxy', {
    type: 'ajax',
    url : '../test',
    reader: {
        type: 'json',
        root: 'responseHeader'
    }
});

But when I pass myProxy1 to a store

Ext.define('Test', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'status', type: 'int'},
        {name: 'QTime',  type: 'int'},
        {name: 'param',  type: 'auto'}
    ]
});

var myStore = Ext.create('Ext.data.Store', {
    model: 'Test',
    proxy: myProxy1,
    autoLoad: true,
    listeners:{
        load: function( ths, records, successful, operation, eOpts ){
            debugger;
        }
    }
});

It doesn't work. The load event is never fired. No data is loaded. I can see that the proxy made the request, I see the response from the server, but it doesn't load.

If I put the proxy inline it loads.

var myStore = Ext.create('Ext.data.Store', {
    model: 'Test',
    proxy:{
       type: 'ajax',
       url : '../test',
       reader: {
         type: 'json',
         root: 'responseHeader'
       }
    },
    autoLoad: true,
    listeners:{
        load:function( ths, records, successful, operation, eOpts ){
         debugger;
        }
    }
});

I was thinking I could have one proxy, attach it to multiple stores, and just change the reader on it before I load the store.

解决方案

You are pretty much there, and although I'm pretty sure you are understanding it all, for the benefit of others allow me to give an extended answer and a slightly modified solution to your problem.

Definitions:

  • The Model - primarily defines the fields a record has.
  • A Store - holds a collection of records.
  • A Proxy - facilitates server communication through a chosen method (Ajax, Direct, etc.) and maps CRUD (Create/Read/Update/Destroy) operations when such result from a change in the associated store or model.
  • A Reader - Tells a proxy how to interpret the data the server returns.
  • A Grid or Combobox - can display store records.

You scenario is not an uncommon one - while by default ExtJS loads each store separately, it is likely an application would prefer various stores to be loaded at once through a single read call; for example, when rendering one store-dependent component is dependent on another store.

Your code is not far off from achieving this, but here is how I do it. In effect, when a 'master' (Tasks) store loads, the server response also carries the data of a 'slave' (Tags) store, which is then manually loaded to that 'slave' store.

The 'slave' store (notice autoload: false and no read operation):

Ext.define('DL.store.Tags', {
    extend: 'Ext.data.Store',    
    model: 'DL.model.Tag',

    // Notice the tags are actually returned when the tasks are loaded and loaded into this store by the TasksStore.
    autoLoad: false, 
    autoSync: true,

    proxy: {
        type: 'direct',

        api: {
            create:  Tags.Create,
            update:  Tags.Update,
            destroy: Tags.Destroy,
        },

        reader: {
            type: 'json',
            root: 'tags'
        }        
    },    

});

Then the 'master' store:

Ext.define('DL.store.Tasks', {
    extend: 'Ext.data.TreeStore',    
    model: 'DL.model.Task',

    autoLoad: true,   
    autoSync: true,

    root: {
        text: 'Root',
        id: null,
        expanded: true
    },

    proxy: {
        type: 'direct',

        api: {
            create:  Tasks.Create,
            read:    Tasks.Read,
            update:  Tasks.Update,
            destroy: Tasks.Destroy,
        },

    },

    onProxyLoad: function( aOperation )
    {
        // A read request for tasks will also return the user tags.
        // So feed these tags into their store.
        var iResult = aOperation.response.result,
            iTagsStore = Ext.StoreManager.lookup( 'Tags' );

        if ( Ext.isDefined( iResult.tags ) )
            iTagsStore.loadRawData( iResult );

        // We need this line for "Tasks" store to load its own data
        this.callParent(arguments);       
    }
});

Basically all it does is it takes part of the server response and loads it manually to the 'slave' store.

The PHP server side code (for tasks read operation) involves:

return array(
    'success'  => true,
    'children' => $iNodes,
    'tags' => $iTags            
);

Where children is the reader's root of the 'master' store, and tags is additional data that is then loaded into the 'slave' store.

I hope you can work how how to apply these concepts to your code.

这篇关于Extjs4:如何在多个商店或模型之间共享数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆