Extjs 在Ext.DataView中显示存储的有限子集(或单个记录)

Extjs 在Ext.DataView中显示存储的有限子集(或单个记录),extjs,sencha-touch,Extjs,Sencha Touch,在Sencha Touch中,我经常需要一个Ext.DataView面板,其中包含一个小的子集记录,甚至是存储区集合中的一条记录 例如,我可能有一个Car的模型,它在app.stores.carsstore中有数千条汽车记录,但我想在我的列表中显示这些项目的一小部分(比如,只有跑车),同时在我的列表中显示更大的完整汽车集DataView 我的第一个想法是使用多个商店。因此,我会有一个主商店来存放所有汽车的大列表,还有一个第二个商店,带有一个过滤器来过滤我的跑车子集。但是,现在从一个存储更新模型并

在Sencha Touch中,我经常需要一个Ext.DataView面板,其中包含一个小的子集记录,甚至是存储区集合中的一条记录

例如,我可能有一个
Car
的模型,它在
app.stores.cars
store中有数千条汽车记录,但我想在我的列表中显示这些项目的一小部分(比如,只有跑车),同时在我的列表中显示更大的完整汽车集
DataView

我的第一个想法是使用多个商店。因此,我会有一个主商店来存放所有汽车的大列表,还有一个第二个商店,带有一个过滤器来过滤我的跑车子集。但是,现在从一个存储更新模型并不会自动更新另一个存储中的记录,因此这就违背了使用DataView的目的,因为更新记录时页面中的所有地方都不会更新更改

我的第二次尝试是覆盖DataView上的
collectData
方法,这听起来与我所追求的完全一样:

var card = new Ext.DataView({
    store: app.stores.cars,
    collectData: function(records, startIndex){
        // map over the records and collect just the ones we want
        var r = [];
        for( var i=0; i<records.length; i++ )
            if( records[i].data.is_sports_car )
                r.push( this.prepareData(records[i].data, 0, records[i]) );
            return r;
    },
    tpl: new Ext.XTemplate([
            '<tpl for=".">',
                  '<div class="car">{name}</div>',
            '</tpl>'
    ]),
    itemSelector: 'div.car'
});
var卡=新的Ext.DataView({
商店:app.stores.cars,
collectData:函数(记录、startIndex){
//在记录上绘制地图,收集我们想要的
var r=[];
对于(var i=0;i我使用存储中的“过滤器”功能。不修改数据视图(我使用列表)

这里有一个片段,我将用一个适合正则表达式的类别来筛选程序

您可以按如下方式清除过滤器:

MyApp.stores.Programs.clearFilter(false);
root: function(data) {
                    if (data) {
                        if (data instanceof Array) {
                            return data;
                        } else {
                            return [data];
                        }                    
                    }  
这将立即更新数据视图(我使用了一个列表)(这太神奇了)

所以在你的过滤器里,你可以过滤掉跑车,或者某个价格的车,或者其他任何东西


希望这有帮助…

您可以使用过滤器来获取与该存储相关的数据子集

yourstore.filter('name', 'Joseph');
您还应该将“root”定义为一个函数,这样它将始终返回一个数组。sencha中的读者会联系asume,您总是会得到一个数组作为响应,但如果您的JSON只有一个条目,则不是这样,请尝试以下操作:

MyApp.stores.Programs.clearFilter(false);
root: function(data) {
                    if (data) {
                        if (data instanceof Array) {
                            return data;
                        } else {
                            return [data];
                        }                    
                    }  
商店的完整代码可能如下所示:

YourApp.ViewName = new Ext.data.Store({
    model: 'YourApp.models.something',
    proxy: {
        type: 'scripttag',
        url: 'http://somerandomurl/service/json',
        extraParams: {
            param1: 'hello'                 
        },
        reader: {
            type: 'json',
            root: function(data) {
                    if (data) {
                        if (data instanceof Array) {
                            return data;
                        } else {
                            return [data];
                        }                    
                    }                
                }
        }
    },

});

希望有帮助。

如评论中所述:


我在上一个Sencha Touch版本中使用了您的演示代码,并用Google Chrome打开了所有。在当前版本中,错误已被修复。(1.1版)

就我对Sencha Touch的理解而言,这不是最好的方法。 如果它仍然能够保持良好的性能,那么您应该使用第二个“从属”存储,并带有内联数据(http://docs.sencha.com/touch/1-1/#!/api/Ext.data.Store),您可以从主存储中自动填充事件在主存储上发生时要显示的信息子集,即加载事件

如果您只想处理一个存储,我可以想象一个解决方案是在dataview中使用一个带有“tpl If”标记的xtemplate,您只想在其中显示一些信息
。写入空记录。也许,更好的解决方案是在xtemplate中使用自定义筛选函数,以便在您不想看到的项目上隐藏具有可见性的css。

问得好。我也使用多个存储区,希望知道是否有更好的方法。您到底从何处得到错误?您尝试过吗若要调试此?@sa,当记录更改时运行
replaceElement
时,ST似乎会盲目地尝试在所有数据视图中查找和替换该记录的HTML,并且不会尝试完全刷新数据视图。由于尝试更新过滤器中找不到的记录,因此会引发
parentNode not found
错误d/收集列表。如果有人想尝试,我已经添加了一个指向完整gist示例的链接。我在上一个ST版本中使用了您的演示代码,并用chrome打开了所有示例。但是没有错误。如果我按下按钮,视图将由斯柯达更新。请提供有关错误的更多信息?如测试环境、版本等…@sra我很笨。添加一个答案,告诉我更新到最新的ST(我的错误现在已修复)并申请您的赏金。我没有注意到我在上一版本上运行。但据我所知,向存储添加
过滤器将影响绑定到该存储的所有数据视图/列表。因此,如果页面上有两个列表相邻,都绑定到同一存储,则设置过滤器将意味着两个列表都将ld被过滤。但目的是让这两个列表显示来自同一商店的不同数据集。是的,你是对的,你可能需要确保你的问题清楚,这就是你要寻找的答案。我将密切关注解决方案…collectData()自Sencha Touch 2.0以来一直存在。