【问题标题】:Extjs4: How to share data between multiple stores or models?Extjs4:如何在多个商店或模型之间共享数据?
【发布时间】:2012-08-13 03:32:03
【问题描述】:

我是 Ext 的新手,我正在努力找出模型商店和代理。

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

{ 
    "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" ]
        }
    }
}

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

我如何加载这些数据一次,然后创建模型和存储以提供给网格和选择框?

从我读到的代理持有服务器响应?所以我尝试在商店外创建一个代理。认为我可以将同一个代理与多个商店一起使用。

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

但是当我将 myProxy1 传递给商店时

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;
        }
    }
});

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

如果我将代理内联,它会加载。

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;
        }
    }
});

我在想我可以有一个代理,将它附加到多个商店,然后在加载商店之前更改其上的阅读器。

【问题讨论】:

    标签: extjs extjs4


    【解决方案1】:

    您几乎就在那里,虽然我很确定您已经理解了这一切,但为了其他人的利益,请允许我为您的问题提供扩展答案和稍微修改的解决方案。

    定义:

    • 模型 - 主要定义记录具有的字段。
    • Store - 保存一组记录。
    • 代理 - 通过选择的方法(Ajax、Direct 等)促进服务器通信,并在关联的更改导致 CRUD(创建/读取/更新/销毁)操作时映射商店或模型。
    • Reader - 告诉代理如何解释服务器返回的数据。
    • GridCombobox - 可以显示商店记录。

    您的情况并不少见 - 虽然默认情况下 ExtJS 单独加载每个存储,但应用程序可能更希望通过单个读取调用一次加载多个存储;例如,当渲染一个依赖于商店的组件时,它依赖于另一个商店。

    您的代码距离实现这一目标不远,但我是这样做的。实际上,当加载“主”(任务)存储时,服务器响应还携带“从”(标签)存储的数据,然后手动加载到该“从”存储。

    'slave' 存储(通知autoload: false 并且没有读取操作):

    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'
            }        
        },    
    
    });
    

    然后是“主”商店:

    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);       
        }
    });
    

    基本上它所做的只是获取服务器响应的一部分并将其手动加载到“从”存储。

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

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

    其中children 是读取器的“主”存储的根,tags 是随后加载到“从”存储的附加数据。

    我希望您能研究如何将这些概念应用到您的代码中。

    【讨论】:

    • 您的主(任务)商店没有阅读器或代理。但是奴隶(标签)商店两者都有。我认为主存储会有代理,而从属不会。 master 会加载数据,onProxyLoad 会将数据块传递给 slave 存储。我有点迷失为什么奴隶有代理而主人在你的例子中没有。
    • 对不起。我在任务模型上有我的代理,因为在以前版本的带有 TreeStore 的 ExtJS 中存在错误。我已经更新了我的代码。
    • 如果 ExtJS 在商店中找不到代理,它会使用关联模型上的代理。
    • 你是对的,你可能没有aOperation.response.result - 最好的办法是console.dir(aOperation) 并通过你的具体调用查看它的结构。
    猜你喜欢
    • 2012-04-19
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2021-12-23
    相关资源
    最近更新 更多