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

Posted

技术标签:

【中文标题】在 Ext.DataView 中显示存储的有限子集(或单个记录)【英文标题】:Showing a limited subset of (or individual record from) a store in an Ext.DataView 【发布时间】:2011-03-27 13:00:19 【问题描述】:

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

例如,我可能有一个 Car 的模型,它的 app.stores.cars 商店中有数千条汽车记录,但我想展示这些项目的一小部分(比如;只是跑车 ) 在我的 listOfSportsCars DataView 中,同时还在我的 listOfCars 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'
);

可以在here找到一个完整的例子。

但是,尽管有记录表明我可以/应该重写此方法,但 Sencha Touch 真的 不喜欢你弄乱 collectData 返回的数组的长度,所以这已经死了-结束。

其他人如何处理显示/更新相同记录的多个集合?

更新 有一个错误阻止 collectData 按预期工作。该错误已在 Sencha Touch 1.1.0 中得到修复。

【问题讨论】:

好问题。我也在使用多家商店,想知道是否有更好的方法。 你到底是从哪里得到错误的?你试过调试这个吗? @sa 在记录更改时运行replaceElement 时,ST 似乎盲目地尝试查找和替换所有数据视图中记录的 html,并且不会尝试完全刷新数据视图。由于尝试更新在过滤/收集列表中找不到的记录,它会引发parentNode not found 错误。如果有人想尝试一下,我已经添加了一个指向完整要点示例的链接。 我在最新的 ST 版本中使用了你的演示代码,并用 chrome 打开了所有内容。但是没有错误。如果我按下按钮,视图就会用斯柯达更新。您能否提供有关该错误的更多信息?比如测试环境、版本等等…… @sra 我很密集。添加一个答案,告诉我更新到最新的 ST(我的错误现在已修复)并领取您的赏金。我没有注意到我运行的是以前的版本。 【参考方案1】:

如评论中所写:

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

【讨论】:

collectData() 自 Sencha Touch 2.0 以来一直是 removed。【参考方案2】:

您可以使用过滤器来获取与该商店关联的数据子集。

yourstore.filter('name', 'Joseph');

您还应该将“root”定义为一个函数,以便它始终返回一个数组。 sencha touch 的读者假设你总是会得到一个数组作为响应,但如果你有一个带有单个条目的 JSON,那就不是真的了,试试这样:

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];
                                            
                                    
                
        
    ,

);

希望对你有帮助。

【讨论】:

【参考方案3】:

我使用商店中的“过滤器”功能。不修改 DataView(我使用 List)。

这是一个 sn-p,我将在其中使用适合正则表达式的类别来筛选程序。 (我有带有类别字段的程序)

MyApp.stores.Programs.filter(function(object) 
    var regex = new RegExp(filterValue, 'i');
    return object.data.category.search(regex) >= 0; // found match
  );

您可以像这样清除过滤器:

MyApp.stores.Programs.clearFilter(false);

这将立即更新 DataView(我使用 List)(这太棒了)。

因此,在您的过滤器中,您可以只过滤掉跑车、特定价格的汽车等。

希望对您有所帮助...

【讨论】:

据我了解;将filter 添加到商店将影响绑定到该商店的所有 数据视图/列表。因此,如果我在页面上有两个彼此相邻的列表,它们都绑定到同一个商店,设置过滤器将意味着 both 列表将被过滤。但目标是能够让两个列表显示一组不同的相同数据——来自同一个商店。 是的,你是对的,你可能想确保你的问题是明确的,那就是你正在寻找的答案。我会留意解决方案...【参考方案4】:

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

如果您只想处理一个商店,我可以想象的解决方案是在您只想显示一些信息的数据视图中使用带有“tpl if”标签的 xtemplate http://docs.sencha.com/touch/1-1/#!/api/Ext。写空记录。也许,还有更好的解决方案,可能是在 xtemplate 中使用自定义过滤器功能,以便在您不想看到的项目上隐藏可见性的 css。

【讨论】:

以上是关于在 Ext.DataView 中显示存储的有限子集(或单个记录)的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 Ext.dataview.List 中的项目?

Sencha Touch:DataView 上看起来像 List Group Header 的组件

编辑填充 x-data-item-inner [关闭]

itemtap 事件未在所有点击时触发

网格内的 ExtJS 组合框

如何在 ExtJS 中实现这个自定义网格?