【问题标题】:Cannot re-apply filters to grid无法将过滤器重新应用于网格
【发布时间】:2012-09-17 22:17:32
【问题描述】:

我有一个需要应用过滤器的网格 (Ext.grid.Panel)。这些过滤器将是预定义的(与您通过从网格列下拉列表中手动选择它们来设置的过滤器相反。)

我有两个功能:

// Clear filter
function() {
    grid.filters.clearFilters();
}

// Apply filter
function() {
    grid.filters.clearFilters();

    grid.filters.addFilter({
        dataIndex: 'size',
        type: 'list',
        options: ['small', 'medium', 'large', 'extra large'],
        value: ['small', 'medium']
    });

    store.load();
}

第一次应用过滤器效果很好。但是,如果您调用该函数清除过滤器,然后再次尝试应用过滤器,则不会过滤数据。我根本没有收到任何错误或反馈。

我也不确定这是否是添加过滤器的推荐方式。我在网上看到了过滤器直接应用于商店的示例,但据我所见,网格无法识别这些过滤器已到位。

任何帮助将不胜感激。

【问题讨论】:

    标签: extjs extjs4


    【解决方案1】:

    我也必须这样做。它是一个更大的函数的一部分,该函数将 JSON“网格格式对象”(包含任意数量的网格过滤器、可见列以及排序列和方向)应用于呈现的网格面板。

    要求是用户需要能够保存现有网格面板的可见列、应用过滤器和应用排序到具有名称的数据库中,然后能够在以后将这三项重新应用到网格面板以通过选择它们保存的格式来获得相同的过滤器、可见列和排序状态。

    我也不想使用商店过滤器,因为选定的过滤器选项需要在网格面板过滤器功能 UI(网格过滤器下拉菜单)上可见,以防用户想要调整它们。

    以下是用户保存的网格格式 JSON 示例:

    {
    "columns":[
        "first_name",
        "last_name",
        "course",
        "course_room",
        "student_status",
        "start_date",
        "schedule",
        "time_on_course",
        "attendance",
        "this_period",
        "acct_bal"
      ],
    "filters":[{
        "field":"student_status",
        "data":{
            "type":"list",
            "value":"Attending"
        }
    }],
    "sort":{
            "property":"start_date",
            "direction":"ASC"
        }
    }
    

    这里是函数,JSON用作参数:

    applyLogFormat: function(format) {
        var log = this.getLog(),
            format = Ext.JSON.decode(format);
    
        log.filters.autoReload = false;
    
        // apply the grid filters correctly
        log.filters.clearFilters();
        Ext.each(format.filters, function(filter) {
            var gridFilter = log.filters.getFilter(filter.field);
    
            gridFilter.setActive(true);
            switch(gridFilter.type) {
    
                case 'date':
                    var dateValue = Ext.Date.parse(filter.data.value, 'm/d/Y'),
                        value = filter.data.comparison == 'gt' ? {after: dateValue} : {before: dateValue};
    
                    gridFilter = log.filters.getFilter(filter.field);
                    gridFilter.setValue(value);
                    break;
    
                case 'list':
                    gridFilter = log.filters.getFilter(filter.field);
                    gridFilter.menu.setSelected(gridFilter.menu.selected, false);
                    gridFilter.menu.setSelected(filter.data.value.split(','), true);
                    break;
    
                default :
                    gridFilter = log.filters.getFilter(filter.field);
                    gridFilter.setValue(filter.data.value);
                    break;
            }
        });
    
        // remove any pre-existing sorting from the grid
        Ext.each(log.columns, function(column, index) {
            if (column.hasCls('x-column-header-sort-ASC') ||
                column.hasCls('x-column-header-sort-DESC')) {
                log.columns[index].setSortState(null);
                return false;
            }
        });
    
        // show only the specified columns
        log.suspendLayout = true;
        Ext.each(log.columns, function(column) {
            if (column.dataIndex) {
                column.setVisible(Ext.Array.contains(format.columns, column.dataIndex));
            }
        });
        log.suspendLayout = false;
        log.doComponentLayout();
    
        // set the sorter
        if (format.sort) {
            var column = log.down('gridcolumn[dataIndex=' + 
                format.sort.property + ']');
            column.setSortState(format.sort.direction);
            log.filters.autoReload = true;
        } else {
            log.store.sorters.clear();
            log.store.loadPage(1);
            log.filters.autoReload = true;
        }
    }
    

    这一切都是为 4.1.0 完成的

    编辑:

    我意识到实现的一个重要部分在该函数中是不可见的。

    通常情况下,网格面板filter feature 菜单在用户实际单击其中一个之前不会创建。然后它们都被创建了。我想这是为了节省内存?

    显然,在创建过滤器菜单之前,此功能将不起作用。

    为了处理这个问题,我在网格面板的afterrender 事件中明确地创建了它们,以便它们立即可用。即使用户没有单击过滤器菜单之一,此功能也将起作用。

    我使用的是 MVC 模式,所以我从网格面板的控制器中进行了操作,如下所示:

    // code from gridpanel's controller
    var me = this;
    me.control({
    
        'log': {
            afterrender: function() {
                me.getLog().filters.createFilters();
            },
        },
    
        // ... other event handlers
    
    });
    

    【讨论】:

    • 您可以使用该方法重新应用过滤器吗?我尝试的一切,在我打电话给grid.filters.clearFilters() 之后,我无法应用新的过滤器。没有错误或任何东西,并且记录 grid.filters.getFilterData() 显示一个空数组。
    • @Arms 我现在正在我正在开发的应用程序上运行它。我再次检查以确保我没有将任何其他 UX 应用于此网格。除了filterfeature,它是一个普通的网格,但我很确定你已经拥有了。你在争论中传递了什么?另外你使用的是 4.1.0 还是 4.1.1,我不知道是否更改了网格上的某些功能可能会破坏这一点。
    • @Arms 我知道为什么您可能会遇到问题,请参阅上面的编辑。
    • @Geronimo 我在使用网格默认过滤时遇到问题。我将默认过滤器定义为 grid.filters,正如您上面所说,除非用户单击标题菜单,否则我无法弄清楚过滤器将如何处于活动状态。我找了好几天。我也在这里提出一个问题,也许你知道我的解决方案。我的问题:stackoverflow.com/questions/14934186/…
    【解决方案2】:

    在你的网格初始化代码中试试这个

    filtersCfg.createFilters();
    
    filtersCfg.filters.each(function (filter) {
         filter.setActive(true);
         filter.setActive(false);
    });
    

    【讨论】:

      【解决方案3】:

      您为什么要将过滤器应用于grid.filters 而不是grid.store? Ext.data.Store 有以下方法filter()clearFilter()

      【讨论】:

      • 我申请grid.filters的原因请看我原来的问题
      • 网格会识别它。不用担心。我们在所有 wen-apps 中都使用这种方法。像魅力一样工作。
      • 使用store.filter为我过滤数据,但网格列的过滤菜单不知道过滤器,调用grid.filters.clearFilters()没有效果。 FWIW,我关注this example。当我将过滤器直接应用于商店时,是否需要在商店和网格之间进行任何额外的布线?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2018-09-06
      • 1970-01-01
      相关资源
      最近更新 更多