【问题标题】:Ext js sorting custom column by contentsExt js按内容排序自定义列
【发布时间】:2015-10-06 08:19:16
【问题描述】:

我在 ext 中有一个带有一些自定义列的网格,我希望能够对此列进行排序 - 我想按其中显示的内容对其进行排序,但实际上我只是不知道如何定义排序器对于不基于 dataIndex 的列 - 我尝试使用自定义模型,但无法使其正常工作。

{
    text: 'Parent',
    dataIndex: 'Parent',
    renderer: function(value, meta, record) {
        var ret = record.raw.Parent;
        if (ret) {
            return ret.Name;
        } else {
            meta.tdCls = 'invisible';
            return record.data.Name;
        }
    },
    sortable: true
},

【问题讨论】:

  • 我认为这些解决方案在我的情况下都不起作用的原因是因为我使用的是 Pageable Store,而不是 Ext.data.Store。谢谢你们,你们的解决方案在使用 Ext.data.Store 时都有效。

标签: sorting extjs


【解决方案1】:

您应该能够覆盖该列的doSort 方法。这是它的要点。我还创建了一个工作小提琴(http://jsfiddle.net/cfarmerga/LG5uA/)。小提琴使用字段的字符串长度作为排序的属性,但当然您可以应用自己的自定义排序逻辑。

var grid = Ext.create('Ext.grid.Panel',{
    //...
    columns: [
        { text: 'name', dataIndex: 'name', sortable: true },
        {
            text: 'Custom',
            sortable : true,
            dataIndex: 'customsort',
            doSort: function(state) {
                var ds = this.up('grid').getStore();
                var field = this.getSortParam();
                ds.sort({
                    property: field,
                    direction: state,
                    sorterFn: function(v1, v2){
                        v1 = v1.get(field);
                        v2 = v2.get(field);
                        return v1.length > v2.length ? 1 : (v1.length < v2.length ? -1 : 0);
                    }
                });
            }
        }
    ]
   //....  
});

【讨论】:

  • 我设置了你所说的代码块,当它无法工作时,开始控制台记录各种变量,以确保我得到正确的东西。当我单击要排序的列时,它会正确调用 doSort 方法。但是,我在ds.sort(); 方法中放入的控制台日志都没有运行过,因此我得出结论该方法从未运行过。知道这里发生了什么吗?另外,根据 API 文档,不应该是 ds.sort([{property...}]);
  • 我不确定您将如何在 ds.sort 方法中添加 console.log 调用,因为您没有覆盖该方法。我刚刚在sorterFn 函数中添加了一个console.log,它被成功调用。
  • 对不起,这就是我的意思。我有sorterFn: function(one, two) { console.log('one',one); console.log('two',two); one = one.get(field); two = two.get(field); return v1.length &gt; v2.length ? 1 : (v1.length &lt; v2.length ? -1 : 0); } 并且控制台没有显示!
  • 嗯。这很奇怪。我刚刚更新了小提琴以显示我正在尝试的内容。我在排序过程中看到了控制台输出。 jsfiddle.net/LG5uA/5 除非您单击列标题,否则您不会看到该函数被调用,这将启动排序。
  • 对,我在doSort(); 方法中有一个console.log(),每次点击列标题时都会执行
【解决方案2】:

对于 Ext JS 版本 5,看起来 doSort 已被删除,所以我无法覆盖它。相反,我走的是监听sortchange 事件的路线,从那里,我使用了Ext.data.Store.setSorters 方法。由于我使用的数据,代码有点自定义,而且过于复杂,所以请记住这一点 (Fiddle here):

// grid class
initComponent: function() {
  ...
  this.on('sortchange', this.onSortChange, this);
},

onSortChange: function(container, column, direction, eOpts) {
  // check for dayColumnIndex
  if (column && column.dayColumnIndex !== undefined) {
    this.sortColumnByIndex(column.dayColumnIndex, direction);
  }
},

sortColumnByIndex: function(columnIndex, direction) {
  var store = this.getStore();
  if (store) {
    var sorterFn = function(rec1, rec2) {
      var sortValue = false;
      if (rec1 && rec2) {
        var day1;
        var daysStore1 = rec1.getDaysStore();
        if (daysStore1) {
          day1 = daysStore1.getAt(columnIndex);
        }
        var day2;
        var daysStore2 = rec2.getDaysStore();
        if (daysStore2) {
          day2 = daysStore2.getAt(columnIndex);
        }
        if (day1 && day2) {
          var val1 = day1.get('value');
          var val2 = day2.get('value');
          sortValue = val1 > val2 ? 1 : val1 === val2 ? 0 : -1;
        }
      }
      return sortValue;
    };
    if (direction !== 'ASC') {
      sorterFn = function(rec1, rec2) {
        var sortValue = false;
        if (rec1 && rec2) {
          var day1;
          var daysStore1 = rec1.getDaysStore();
          if (daysStore1) {
            day1 = daysStore1.getAt(columnIndex);
          }
          var day2;
          var daysStore2 = rec2.getDaysStore();
          if (daysStore2) {
            day2 = daysStore2.getAt(columnIndex);
          }
          if (day1 && day2) {
            var val1 = day1.get('value');
            var val2 = day2.get('value');
            sortValue = val1 < val2 ? 1 : val1 === val2 ? 0 : -1;
          }
        }
        return sortValue;
      };
    }
    store.setSorters([{
      sorterFn: sorterFn
    }]);
  }
}

【讨论】:

【解决方案3】:

Ext.data.Model 类上有一个转换方法,允许您在使用数据之前对其进行转换。然后你可以在你的列中指定这个'dataIndex'并进行正常排序。该列将按转换后的值排序。这是一个只有一个字段(父级)的示例模型及其相应的转换:

Ext.define('MyModel', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'Parent',   type: 'string', convert: sortParent},
        // other fields...
    ],
    sortParent: function(value, record) {
        var ret = record.raw.Parent;
        if (ret) {
            return ret.Name;
        } else {
            meta.tdCls = 'invisible';
            return record.data.Name;
        }
    }
});

【讨论】:

  • 我尝试了这种方法,但我无法让它发挥作用。我没有看到 convert 方法,也不确定从哪里调用 sortParent 方法。
  • @JuanDanielFlores - 您的示例在备用数据的情况下可以正常工作,但正如最初发布的那样,小提琴的排序在两列之间是相同的。 jsfiddle.net/LG5uA/57 更好地展示了它的工作原理。
猜你喜欢
  • 2019-02-22
  • 1970-01-01
  • 2017-07-30
  • 1970-01-01
  • 2021-04-02
  • 1970-01-01
  • 2013-06-11
  • 2014-12-09
  • 1970-01-01
相关资源
最近更新 更多