Extjs4:如何在多个商店或模型之间共享数据?

Jer*_*naw 9 extjs extjs4

我是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" ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

如何加载此数据一次,然后创建模型和商店以从中提供网格和选择框?

从我读到的代理保存服务器响应?所以我尝试在商店外面创建一个代理.我想我可以在多个商店中使用相同的代理.

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

但是当我将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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

它不起作用.永远不会触发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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

我以为我可以有一个代理,将它附加到多个商店,只需在加载商店之前更改它上面的阅读器.

Izh*_*aki 11

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

定义:

  • 模式 -主要是定义一个记录有字段.
  • 一个商店 -保存记录的集合.
  • 代理 -通过选定的方法促进服务器通信(Ajax的,直等)和映射CRUD(创建/读取/更新/销毁)操作时从在相关联的商店或模型的变化这样的结果.
  • 一个阅读器 -讲述了一个代理如何解释数据的服务器的回报.
  • 一个网格组合框 -可以显示存储记录.

您的场景并不罕见 - 虽然默认情况下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'
        }        
    },    

});
Run Code Online (Sandbox Code Playgroud)

那么'主'商店:

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);       
    }
});
Run Code Online (Sandbox Code Playgroud)

基本上它所做的只是服务器响应的一部分并将其手动加载到"从属"存储.

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

return array(
    'success'  => true,
    'children' => $iNodes,
    'tags' => $iTags            
);
Run Code Online (Sandbox Code Playgroud)

children读者的"主"商店的根源在哪里,然后tags是附加数据,然后加载到"从属"商店.

我希望您可以学习如何将这些概念应用到您的代码中.