【问题标题】:Flex custom sorting capabilities with server side support具有服务器端支持的 Flex 自定义排序功能
【发布时间】:2011-01-19 17:31:51
【问题描述】:

Flex 中可用的排序功能假定您可以访问所有数据,但我使用的是分页数据网格(带有自定义代码),数据网格绑定到 ArrayCollection 实例,在下一页调用我更改 dataprovider 的数据,一切正常,但是对于排序,我需要覆盖单击或事件,更好地覆盖 arraycollection 的排序方法

所有这些都是为了能够进行服务器端排序。

有人遇到过这种问题吗?

【问题讨论】:

    标签: apache-flex sorting datagrid arraycollection


    【解决方案1】:

    这里是我用来解决这个问题的步骤......这个解决方案的好处是我可以让 Flex 和我一起“排序”,这让排序方向图标在 DataGrid 上保持可见。

    步骤:

    1. 使用DataGrid的headerRelease事件拦截“排序”请求。

    2. 保留列的本地映射及其当前排序方向...这是 flex 在其排序上所做的模拟...所以所有列都以“升序”开头,然后方向是仅当连续单击给定列两次时才切换。这可能可以通过观察 flex 内部结构来完成,但我不想尝试。

    3. headerRelease 事件使用其事件中请求的列,以及先前请求的列和当前列排序方向的映射来决定是否更新本地映射中的排序方向。

      李>
    4. 调用服务器以获取适当排序的数据页。

    此时,Flex 也希望对数据进行排序...(除非您阻止默认() headerRelease 事件)...以允许 Flex 对数据进行“排序”而不会弄乱任何东西,从而使方向图标继续正常工作,您可以:

    1. 在服务器上的 SQL 结果集中添加一个“行 id”字段,这只是结果集中每个连续行的计数器,在它被排序和分页之后......这个 id 将始终是升序,无论应用什么排序方向。

    2. 将 DataGridColumns 上的 sortCompareFunction 设置为使用此行 id 的“虚拟”排序...如下所示:

    public function doNothingSort( a:Object, b:Object ):int {
        if( weAreCurrentlyInAscendingDirection )
            return ObjectUtil.numericCompare( a.new, b.num );
        else
            return ObjectUtil.numericCompare( b.num, a.num );
    }
    

    这将允许 flex 遍历“页面”并保持一切原样......所以它很高兴,你很高兴,因为你有图标......

    【讨论】:

    • 我对 Flex 端的“虚拟”排序使用了不同的方法:我在处理函数上使用了 preventDefault。由于我已经有一个排序列的本地映射,因此在从服务器获取数据后,我手动将相同的排序应用于我的 dataProvider。我扩展了 Sort 类并重写了 sort() 函数,所以什么都不做并返回。我在我的数据提供者上使用这个 DummySort 类。
    【解决方案2】:

    我不确定我是否真的理解这个问题,但听起来你需要在服务器端进行排序。如果您没有将所有数据加载到 flex 应用程序中,则无法对其进行排序。

    【讨论】:

    • 没错,我想做服务端排序,但是不知道必须覆盖哪个方法,现在我正在尝试实现sort()方法,但我没有确定这是否是最好的方法,我已经尝试在数据网格标题上覆盖点击事件,但没有好的结果。
    • 我不确定您是否理解我所说的服务器端的意思。您连接到哪种语言来获取数据?不管是什么,你是用sql来检索数据提供给flex的吗?如果是这样,请将您的排序放在那里。 flex 中的重写方法与服务器端完全无关。
    • 您是如何在 AdvancedDataGrid 中实现这种排序的?
    【解决方案3】:

    我是这样理解问题的:

    他在 flex 客户端中拥有总数据的一部分。因为客户端不知道所有的数据,所以不能在客户端进行排序。 他已经让服务器端排序工作了。

    他现在需要做的是:当用户单击数据网格的标题时,他想进行服务器调用并取回排序后的数据。 单击网格标题时的默认行为是数据在客户端排序。 所以这就是为什么他需要做一些客户端的事情。

    我发现的唯一东西是这样的:

    <mx:DataGrid xmlns:mx="http://www.adobe.com/2006/mxml"
    headerRelease="onHeaderRelease(event)">
    

    只要单击标题上的鼠标按钮(再次释放鼠标按钮),就会调用指定的函数onHeaderRelease。

    示例函数。也许你可以从这里取货

            public function onHeaderRelease(evt:DataGridEvent):void
            {
                var grd:DataGrid = DataGrid(evt.currentTarget);
                Alert.show(evt.columnIndex + " : " + (DataGridColumn)(grd.columns[evt.columnIndex]).sortDescending, "ColumnIndex : Sorted Descending?");
                // do the server called and get the sorted array back
            }
    

    希望对你有帮助!

    【讨论】:

    • 感谢 countcb 的回答,我试图避免视觉技巧(连接鼠标单击事件等),主要是因为这不允许我使用几乎标准的网格。
    【解决方案4】:

    我实现了以下解决方案,目前运行良好,但可能还有一些可以改进的地方。

    我扩展了 ArrayCollection 类并重写了排序设置/获取和刷新方法

    package custom
    {
    import mx.collections.ArrayCollection;
    import mx.collections.Sort;
    
    /**
     *  Dispatched when a sort is required
     *
     *  @eventType custom.PaginatedCollectionEvent.SORT
     */
    [Event(name="sort" , type="custom.PaginatedCollectionEvent")]
    
    public class PaginatedCollection extends ArrayCollection
    {
        private var _sort:Sort;
    
        public function PaginatedCollection(source:Array=null)
        {
            super(source);
        }
    
        public function setDefaultSort (s:Sort):void
        {
            _sort = s;
        }
    
    
        override public function set sort(s:Sort):void
        {
            _sort = s;
            if (!s)
                return;
    
            var event:PaginatedCollectionEvent = new PaginatedCollectionEvent(PaginatedCollectionEvent.SORT);
            event.fields = s.fields;
            event.s = s;
            this.dispatchEvent(event);
        }
    
        override public function get sort():Sort
        {
            return _sort;
        }
    
        /**
         * Avoid the internal sorting implementation, with this it's possible
         * to do a server side sort.
         *
         * @return true
         */
        override public function refresh():Boolean
        {
            return true;
        }
    
        /**
         * Wrapper for ArrayCollection refesh implementation
         */
        public function superRefresh():Boolean
        {
            return super.refresh();
        }
    }
    

    }

    【讨论】:

    • 也试过了。不知何故,排序字段为空。
    猜你喜欢
    • 2010-11-22
    • 2011-01-08
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多