注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

神魔破杜梓的叨叨堂

Programming every day!

 
 
 

日志

 
 
 
 

让ArrayCollection 支持分页  

2008-10-09 09:34:23|  分类: My Tech |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
原文来自Flex Cookbook

Problem Summary

ArrayCollection does not support paging

Solution Summary

Adding properties such as "pageSize", "numberOfPages" and "lengthTotal" to the existing ArrayCollection and implementing a filterfunction supporting paging gives a simple pagination addition to the existing ArrayCollection class.

Explanation

Yesterday one of the developers in my company had the need for a PagedArrayCollection. A quick search on Google revealed only this implementation, which turned out to be buggy so I decided to implement one myself.

I designed an interface called IPagedCollection which in combination with an extension of the existing mx.collections.ArrayCollection implementation would do the job.

Only hurdle was the need to override addItemAt and removeItemAt as the autoUpdate doesn’t seem to work when a filterFunction is employed. I will look in to this phenomena, but as for now a call to refresh after inserting or removing does the job nicely.

The code itself is quite simple, I have also created a small demo-application which illustrates the use of the collection.

Live Demo

Download of Sources

 **
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
**/
package com.hello.collections
{
    public interface IPagedArrayCollection
    {
        function get currentPage() : Number;
        function set currentPage( value:Number ) : void;
        function get numberOfPages() : Number;
        function get pageSize() : Number;
        function set pageSize( value:Number ) : void;
        function get lengthTotal() : Number;
    }
}

/**
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
*
* Known Issues:
* - When the collection changes in size or pagesize, the currentPage is not updated.
*   This is a problem if currentPage is set to a higher value than in the new collection.
**/
package com.hello.collections
{
    import mx.collections.ArrayCollection;
    import mx.events.CollectionEvent;

    public class PagedArrayCollection extends ArrayCollection implements IPagedArrayCollection
    {
        private var _currentPage:Number = 1;
        private var _numberOfPages:Number = 1;
        private var _pageSize:Number = 10;
        
        public function PagedArrayCollection( source:Array=null )
        {
            super( source );
            filterFunction = filterData;
            addEventListener( CollectionEvent.COLLECTION_CHANGE, onChange );
        }  

        /**
        * Adds an item to the collection at the specified index.
        *
        * @param item Item to be added
        * @param index Index of the item to be added
        *
        * Note: Needs to be overridden in order to trigger refresh.
        *        AddItem eventually calls this function so its not needed to override addItem
        **/
        override public function addItemAt( item:Object, index:int ) : void
        {
            super.addItemAt( item, index );
            refresh();
        }

        /**
        * Removes the item from the collection at the specified index
        *
        * @param index Index of the item to be removed
        * @return The item removed
        *
        * Note: Needs to be overridden in order to trigger refresh
        **/
        override public function removeItemAt( index:int ) : Object
        {
            var removedItem:Object = super.removeItemAt( index );
            refresh();
            return removedItem;
        }

        protected function onChange( event:CollectionEvent ) : void
        {
            if( _numberOfPages != numberOfPages )
            {
                _numberOfPages = numberOfPages;
                onPagingChange( PagedCollectionEventKind.NUMBEROFPAGES_CHANGE );
            }
        }
        
        protected function onPagingChange( kind:String ) : void
        {
            dispatchEvent( new CollectionEvent( CollectionEvent.COLLECTION_CHANGE, false, false, kind ) );
        }  

        [ChangeEvent("collectionChange")]
        public function get currentPage() : Number
        {
            return _currentPage;
        }
        
        public function set currentPage( value:Number ) : void
        {
            _currentPage = value;
            refresh();
            onPagingChange( PagedCollectionEventKind.CURRENTPAGE_CHANGE );
        }

        [ChangeEvent("collectionChange")]
        public function get numberOfPages() : Number
        {
            var result:Number = source.length / pageSize;
            result = Math.ceil( result );
            return result;
        }
        
        [ChangeEvent("collectionChange")]
        public function get pageSize() : Number
        {
            return _pageSize;
        }
        
        public function set pageSize( value:Number ) : void
        {
            _pageSize = value;
            refresh();
            onPagingChange( PagedCollectionEventKind.PAGESIZE_CHANGE );
        }

        [ChangeEvent("collectionChange")]
        public function get lengthTotal() : Number
        {
            return source.length;
        }

        private function filterData( item:Object ) : Boolean
        {
            var dataWindowCeiling:Number = pageSize * currentPage;
            var dataWindowFloor:Number = dataWindowCeiling - pageSize;
            
            var itemIndex:Number = getItemIndex( item );
            var result:Boolean = dataWindowFloor <= itemIndex && itemIndex < dataWindowCeiling;
            
            return result;
        }
    }
}

/**
* Copyright(c) 2008 HelloGroup A/S, some rights reserved.
* Your reuse is governed by the Creative Commons Attribution 3.0 Denmark License
 **/
package com.hello.collections
{
    public class PagedCollectionEventKind
    {
        public static const CURRENTPAGE_CHANGE:String = "currentPageChange";
        public static const PAGESIZE_CHANGE:String = "pageSizeChange";
        public static const NUMBEROFPAGES_CHANGE:String = "numberOfPagesChange";
    }
} 
 

This is the small demo-application which illustrates and validates that the collection works.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    initialize="onInitialize(event)"
    creationComplete="onCreationComplete(event)">

    <mx:HBox width="100%">
        <mx:Label text="Key:" />
        <mx:TextInput id="keyInput" text="NEW KEY" />
        <mx:Label text="Value:" />
        <mx:TextInput id="valueInput" text="NEW VALUE" />
        <mx:Button id="addButton" label="Add Item" />
        <mx:Button id="removeButton" label="Remove Item" enabled="{ grid.selectedItem != null }" />
        <mx:Label text="Set PageSize:" />
        <mx:ComboBox id="pageSizeSelector" dataProvider="{ [ 5, 10, 25] }" selectedIndex="1" change="{ collection.pageSize = Number( pageSizeSelector.value ) }" />
    </mx:HBox>
    
    <mx:DataGrid id="grid" dataProvider="{ collection }" width="100%" height="100%" />
    
    <mx:HBox>
        <mx:Label text="Count: { collection.length } ({ collection.lengthTotal })" />
        <mx:Label text="( { collection.currentPage }/{ collection.numberOfPages } )" />
        <mx:Label text="PageSize: { collection.pageSize }" />
        <mx:Button label="Previous" enabled="{ collection.currentPage > 1 }" click="{ collection.currentPage-- }" />
        <mx:Button label="Next" enabled="{ collection.numberOfPages > collection.currentPage }" click="{ collection.currentPage++ }" />
    </mx:HBox>  

    <mx:Script>
    <![CDATA[
    
    import mx.events.CollectionEvent;
    import mx.events.FlexEvent;
    import com.hello.collections.PagedArrayCollection;

    [Bindable]
    private var collection:PagedArrayCollection;
    
    private function onInitialize( event:FlexEvent ) : void
    {
        var collection:Array = new Array();
        for( var i:Number = 1; i <= 20; i++ )
        {
            collection.push( { key:"Item_Key_"+ i, value:"Item_Value_"+ i } );
        }
        this.collection = new PagedArrayCollection( collection );
        this.collection.addEventListener( CollectionEvent.COLLECTION_CHANGE, onItemsChange );
        this.collection.refresh();
    }
        
    private function onCreationComplete( event:FlexEvent ) : void
    {
        addButton.addEventListener( MouseEvent.CLICK, addButton_Click );
        removeButton.addEventListener( MouseEvent.CLICK, removeButton_Click );
    }

    private function addButton_Click( event:MouseEvent ) : void
    {
        collection.addItem( { key:keyInput.text, value:valueInput.text } );
    }

    private function removeButton_Click( event:MouseEvent ) : void
    {
        collection.removeItemAt( collection.getItemIndex( grid.selectedItem ) );
    }

    private function onItemsChange( event:CollectionEvent ) : void
    {
        trace( event.kind +" collectionchanged" );
    }

    ]]>
    </mx:Script>
    
</mx:Application>


  评论这张
 
阅读(421)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017