草庐IT

javascript - ExtJS 4 Grid 自定义列排序(文件管理器样式)

coder 2024-07-23 原文

我正准备使用 ExtJS 4 制作一个基本的文件管理器。我现在面临的问题是:如何为 grid panel 进行自定义排序单击列时

假设我们有商店字段:

[
    { name: "is_dir", type: "boolean" },
    { name: "name",   type: "string"  },
    { name: "size",   type: "int"     }
]

以及来自数组的数据:

[
    { is_dir: true,  name: "..",        size: 0    },
    { is_dir: false, name: "file2.txt", size: 512  },
    { is_dir: true,  name: "folder2",   size: 0    },
    { is_dir: false, name: "file3.txt", size: 1024 },
    { is_dir: true,  name: "folder1",   size: 0    },
    { is_dir: true,  name: "file1.txt", size: 1024 },
    // ...
]

想法是像在任何文件管理器中一样进行排序(例如 Total CommanderMCFAR 等),因此:

  • 名称为“..”的项目总是放在顶部
  • 目录按排序顺序在“..”(如果存在)之后
  • 文件按排序顺序排在目录(如果存在)之后

例如,按名称和大小排序的输出应该是:

^ Name           | Size               Name             | ^ Size
-----------------------               -------------------------
..               | 0                  ..               | 0
folder1          | 0                  folder1          | 0
folder2          | 0                  folder2          | 0
file1.txt        | 1024               file2.txt        | 512
file2.txt        | 512                file1.txt        | 1024
file3.txt        | 1024               file3.txt        | 1024

我尝试为存储 sorters 属性编写自定义 sorterFn,但它没有帮助。我相信应该有一些简单的解决方案。

最佳答案

您可以重写商店的 sort 方法:

Ext.define('My.store.FileStore', {
    extend: 'Ext.data.Store',

    sort: function () {
        this.doSort(function() {
            // Custom sorting function
            console.log(arguments);
            return Math.random() > 0.5 ? 1 : -1; // :)
        });
    }
});

更新

Ext.define('FileModel', {
    extend: 'Ext.data.Model',
    fields: [
        { name: "is_dir", type: "boolean" },
        { name: "name",   type: "string"  },
        { name: "size",   type: "int"     }
    ]
});

Ext.define('FileStore', {
    extend: 'Ext.data.Store',
    model: 'FileModel',
    data: [
        { is_dir: true,  name: "..",        size: 0    },
        { is_dir: false, name: "file2.txt", size: 512  },
        { is_dir: true,  name: "folder2",   size: 0    },
        { is_dir: false, name: "file3.txt", size: 1024 },
        { is_dir: true,  name: "folder1",   size: 0    },
        { is_dir: false, name: "file1.txt", size: 1024 },
    ],

    sorters: [{
        property: 'name',
        direction: 'ASC'
    }],

    sort: function(params) {
        var dir = params ? params.direction : 'ASC';
        var prop = params ? params.property : 'name';

        this.callParent(arguments); // UPDATE 2                    

        this.doSort(function(rec1, rec2) {
            var rec1sort = '';
            var rec2sort = '';

            if (rec1.get('is_dir') && rec2.get('is_dir')) {
                // both dirs
                if (rec1.get('name') == '..') {
                    return -1;
                }
                else if (rec2.get('name') == '..') {
                    return 1;
                }
                else {
                    return rec1.get('name').localeCompare(rec2.get('name')) * (dir == 'ASC' ? 1 : -1);;
                }
            }
            else if (rec1.get('is_dir') != rec2.get('is_dir')) {
                // file and dir
                if (rec1.get('is_dir')) {
                    if (rec1.get('name') == '..') {
                        return -2;
                    }
                    else {
                        return -1;
                    }
                }
                else {
                    if (rec2.get('name') == '..') {
                        return 2;
                    }
                    else {
                        return 1;
                    }
                }
            }
            else if (!rec1.get('is_dir') && !rec2.get('is_dir')) {
                // both files
                var result;
                if (typeof rec1.get(prop) == 'number') {
                    result = rec1.get(prop) - rec2.get(prop);
                    if (result == 0) {
                        result = rec1.get('name').localeCompare(rec2.get('name'));
                    }
                }
                else {
                    result = rec1.get('name').localeCompare(rec2.get('name'));
                }
                return dir == 'ASC' ? result : result * -1;
            }
        });
    }
});    

var grid = Ext.create('Ext.grid.Panel', {
    title: 'Files',
    store: Ext.create('FileStore'),
    renderTo: Ext.getBody(),
    columns: [{
        header: 'Name',
        dataIndex: 'name'
    }, {
        header: 'Size',
        dataIndex: 'size'    
    }]
});

关于javascript - ExtJS 4 Grid 自定义列排序(文件管理器样式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12932007/

有关javascript - ExtJS 4 Grid 自定义列排序(文件管理器样式)的更多相关文章

  1. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  2. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  3. ruby-on-rails - 如何在 Rails 3 中创建自定义脚手架生成器? - 2

    有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我

  4. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  5. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  6. ruby-on-rails - Rails - 使用/自定义 URL : '/dashboard' 指定根路径 - 2

    如何使此根路径转到:“/dashboard”而不仅仅是http://example.com?root:to=>'dashboard#index',:constraints=>lambda{|req|!req.session[:user_id].blank?} 最佳答案 您可以通过以下方式实现:root:to=>redirect('/dashboard')match'/dashboard',:to=>"dashboard#index",:constraints=>lambda{|req|!req.session[:user_id].b

  7. ruby-on-rails - 在 heroku 的 .fonts 文件夹中包含自定义字体,似乎无法识别它们 - 2

    Heroku支持人员告诉我,为了在我的Web应用程序中使用自定义字体(未安装在系统中,您可以在bash控制台中使用fc-list查看已安装的字体)我必须部署一个包含所有字体的.fonts文件夹里面的字体。问题是我不知道该怎么做。我的意思是,我不知道文件名是否必须遵循heroku的任何特殊模式,或者我必须在我的代码中做一些事情来考虑这种字体,或者如果我将它包含在文件夹中它是自动的......事实是,我尝试以不同的方式更改字体的文件名,但根本没有使用该字体。为了提供更多详细信息,我们使用字体的过程是将PDF转换为图像,更具体地说,使用rghostgem。并且最终图像根本不使用自定义字体。在

  8. ruby-on-rails - Heroku 吃掉了我的自定义 HTTP header - 2

    我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份​​验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby​​脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara

  9. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐